我试图用std::list
类型的成员创建线程局部单例类。在使用多线程测试我的解决方案期间,我遇到了std::list
析构函数(更确切地说,是_M_clear()
由析构函数调用的方法)引起的崩溃。即使没有对提到的列表执行任何操作,它也会发生。更奇怪的是,此崩溃是随机发生的。
任何想法,这里可能有什么问题?
以下是减少此错误的最小示例:
#include <list>
#include <thread>
class tls_list_test
{
private:
std::list<int> test_list;
tls_list_test() = default;
~tls_list_test() = default;
public:
static tls_list_test& get_instance()
{
thread_local tls_list_test instance;
return instance;
}
};
int main()
{
std::list<std::thread> threads;
for (int i = 0; i < 3; ++i)
{
std::thread thread([]()
{
auto& instance = tls_list_test::get_instance();
});
threads.push_back(std::move(thread));
}
for (auto& thread : threads)
{
thread.join();
}
return 0;
}
std::list
中的代码会导致段错误:
template<typename _Tp, typename _Alloc>
void
_List_base<_Tp, _Alloc>::
_M_clear() _GLIBCXX_NOEXCEPT
{
typedef _List_node<_Tp> _Node;
__detail::_List_node_base* __cur = _M_impl._M_node._M_next;
while (__cur != &_M_impl._M_node)
{
_Node* __tmp = static_cast<_Node*>(__cur);
__cur = __tmp->_M_next; // <- SEGFAULT on this line
_Tp* __val = __tmp->_M_valptr();
#if __cplusplus >= 201103L
_Node_alloc_traits::destroy(_M_get_Node_allocator(), __val);
#else
_Tp_alloc_type(_M_get_Node_allocator()).destroy(__val);
#endif
_M_put_node(__tmp);
}
}
GDB变量:
Signal = SIGSEGV (Segmentation fault)
__tmp = {std::__cxx11::_List_base<int, std::allocator>::_Node * | 0xfeeefeeefeeefeee} 0xfeeefeeefeeefeee
__val = {int * | 0x2ee4448} 0x2ee4448
this = {std::__cxx11::_List_base<int, std::allocator> * const | 0x2ee5be8} 0x2ee5be8
__cur = {std::__detail::_List_node_base * | 0xfeeefeeefeeefeee} 0xfeeefeeefeeefeee
G ++版本:
g++ (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 8.1.0
答案 0 :(得分:0)
唯一可能的原因是在编译器上实现const exec = require('child_process').exec;
let data;
const command = "df -g | awk '$4+0 >= 80 { print $4, $7 }' | sort -n";
let exe = exec("ssh user@sistemName " + command, function (error, data, stderr ) {
});
console.log(data);
。本地变量不是(暗示)thread_local
。尝试将static
添加到(本地)变量中:
static
答案 1 :(得分:0)
在8.4之前的所有gcc版本中,都有一个bug用于处理本地函数thread_local
。
使用较新的gcc版本,或者使用类静态或命名空间范围为thread_local
的类。