3

我正在将一个 C++ 程序从 FreeBSD 移植到 RHEL。当我测试我的程序时,我发现调用 boost::shared_ptr::~shared_ptr() 时进程会挂起。

我使用 gdb 附加挂起进程,堆栈跟踪是:

(gdb) bt
#0  0x00e01430 in __kernel_vsyscall ()
#1  0x00bd8d96 in __pause_nocancel () from /lib/libpthread.so.0
#2  0x00bd30b2 in __pthread_mutex_lock_full () from /lib/libpthread.so.0
#3  0x04a60a26 in pthread_mutex_lock () from /lib/libc.so.6
#4  0x08069b61 in boost::detail::lightweight_mutex::scoped_lock::scoped_lock(boost::detail::lightweight_mutex&) ()
#5  0x080699d3 in boost::detail::sp_counted_base::release() ()
#6  0x08069999 in boost::detail::shared_count::~shared_count() ()
#7  0x08069952 in boost::shared_ptr<SS::Conf::SSConfNode>::~shared_ptr() ()
#8  0x00124fde in SS::Conf::SSConfManager::createConfFile(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) () from /home/y/lib/libSS_conf.so.1
#9  0x00125e0c in SS::Conf::SSConfManager::createAllConfFiles() () from /home/y/lib/libSS_conf.so.1
#10 0x0012946b in SS::Conf::SSConfManager::initFromDisk(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) () from /home/y/lib/libSS_conf.so.1
#11 0x00129c3b in SS::Conf::SSConfManager::configure(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) () from /home/y/lib/libSS_conf.so.1
#12 0x00156d0c in SS::Init::configure() () from /home/y/lib/libSS_init.so.1
#13 0x0805ac63 in SS::Main::init() ()
#14 0x0807117e in main ()

而我的进程只包含一个线程:

(gdb) info thread
* 1 Thread 0xf77a8a40 (LWP 16724)  0x00c54430 in __kernel_vsyscall ()

当我在头文件中取消定义BOOST_HAS_THREADS并重建程序时,一切顺利。

boost 版本是 1.32,我在 RHEL4.8 上使用 gcc 3.4.6-11。

4

2 回答 2

3

我不确定问题是什么,但这可能是1.32 文档中的相关部分:

shared_ptr用于Boost.Config检测实现是否支持线程。如果您的程序是单线程的,但您的平台被自动检测Boost.Config为支持多线程,#define BOOST_DISABLE_THREADS以消除线程安全开销。

因此,考虑使用#define BOOST_DISABLE_THREADS而不是 undefined BOOST_HAS_THREADS

这是1.33 及更高版本的文档

从 Boost 版本 1.33.0 开始,shared_ptr在以下平台上使用无锁实现:

  • x86 或 x86-64 上的 GNU GCC;
  • IA64 上的 GNU GCC;
  • PowerPC 上的 Metrowerks CodeWarrior;
  • PowerPC 上的 GNU GCC;
  • 视窗。

如果您的程序是单线程的并且没有链接到任何可能在其默认配置中使用 shared_ptr 的库,您可以#define在项目范围内使用宏BOOST_SP_DISABLE_THREADS切换到普通的非原子引用计数更新。

BOOST_SP_DISABLE_THREADS在某些(但不是全部)中定义翻译单元在技术上违反了单一定义规则和未定义的行为。然而,实现尝试尽最大努力满足在这些翻译单元中使用非原子更新的请求。不保证, 尽管。)

您可以定义宏BOOST_SP_USE_PTHREADS以关闭特定于平台的无锁实现并回退到pthread_mutex_t基于通用的代码。

于 2012-06-08T17:29:19.217 回答
0

最后我找到了原因。我的主程序使用 boost 1.32 构建,但我的 .so 文件之一是使用 boost 1.38 构建的。运行我的程序并导致此问题时,有 2 个 shared_ptr 实现。在我用 boost 1.32 重建我的 so 文件后,程序运行良好。

于 2012-06-09T16:07:38.273 回答