boost::shared_ptr的析构函数阻止了唯一的线程
boost::shared_ptr's destructor block the only thread
我正在将一个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并重建程序时,一切顺利。
提升版本是 1.32,我在 RHEL3.4.6-11 上使用 gcc 4.8。
我不确定问题是什么,但这可能是 1.32 文档中的相关部分:
shared_ptr
使用Boost.Config
来检测实现是否支持线程。如果您的程序是单线程的,但您的平台被Boost.Config
自动检测为支持多个线程,#define BOOST_DISABLE_THREADS
消除线程安全开销。
因此,请考虑使用 #define BOOST_DISABLE_THREADS
而不是取消定义BOOST_HAS_THREADS
。
这是 1.33 及更高版本的文档:
从 Boost 版本 1.33.0 开始,
shared_ptr
在以下平台上使用无锁实现:
- x86 或 x86-64 上的 GNU GCC;
- GNU GCC on IA64;
- PowerPC上的Metrowerks CodeWarrior;
- GNU GCC on PowerPC;
- 窗户。
如果您的程序是单线程的,并且未链接到可能在其默认配置中使用了shared_ptr的任何库,则可以在项目范围内
(#define
宏BOOST_SP_DISABLE_THREADS
,以切换到普通的非原子引用计数更新。在某些(但不是全部)翻译单元中定义
BOOST_SP_DISABLE_THREADS
在技术上违反了一个定义规则和未定义的行为。尽管如此,实现会尽力满足在这些翻译单元中使用非原子更新的请求。不过,不能保证。您可以定义宏
BOOST_SP_USE_PTHREADS
以关闭特定于平台的无锁实现,并回退到基于通用pthread_mutex_t
的代码。
终于找到了原因。我的主程序使用 boost 1.32 构建,但我的一个 .so 文件构建与 boost 1.38。运行我的程序时有 2 个shared_ptr实现并导致了此问题。我使用 boost 1.32 重建我的 so 文件后,程序运行良好。
- 从不同线程使用int64的不同字节安全吗
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 在C++中使用cURL和多线程
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 在cuda线程之间共享大量常量数据
- 如何将元素添加到数组的线程安全函数?
- 线程,如果else语句,都是错误的上下文切换后,会发生什么
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- Qt C++静态thread_local QNetworkAccessManager是线程应用程序的好选择吗
- 异常属于C++中的线程还是进程
- C++中的线程安全删除
- C++使用params创建线程函数会导致转换错误
- 类与私有变量的其他类之间的线程安全性
- CoInitialize()在单独的线程上崩溃而不返回
- C++11:具有互斥锁的线程看到原子变量的值发生变化,尽管这是唯一可以改变它的代码
- 我可以使用Qt线程ID为每个线程创建唯一的缓存吗?
- 您可以在 OpenMP 中将特定线程 ID 分组到唯一的任务组中吗?
- boost::shared_ptr的析构函数阻止了唯一的线程
- 在另一个线程中分配唯一ptr的错误
- 嵌套函数的线程安全和唯一执行