首页 > 解决方案 > C++ 使用 list.remove() 在多线程使用时会导致分段错误

问题描述

我正在模拟客户坐在桌子上然后离开桌子。我当前的表数据结构是一个包含线程指针的列表。

list<intptr_t> table;

void * customer(void* vargp){
    intptr_t tid;
    tid = (intptr_t)vargp;
    //enter table
    table.push_back(tid);

    //do actions at table

    //leave table   
    table.remove(tid);
}

我有一个间歇性的分段错误,我很确定这来自两个试图同时从表中删除自己的线程。使用 gdb,这是我找到的回溯:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x2aaacf005700 (LWP 44705)]
0x00000000004032db in std::_List_const_iterator<long>::operator++ (this=0x2aaacf004e10) at /usr/include/c++/4.8.2/bits/stl_list.h:235
235             _M_node = _M_node->_M_next;
Missing separate debuginfos, use: debuginfo-install glibc-2.17-324.el7_9.x86_64 libgcc-4.8.5-44.el7.x86_64 libstdc++-4.8.5-44.el7.x86_64
(gdb) bt
#0  0x00000000004032db in std::_List_const_iterator<long>::operator++ (this=0x2aaacf004e10) at /usr/include/c++/4.8.2/bits/stl_list.h:235
Python Exception <type 'exceptions.ValueError'> Cannot find type std::_List_const_iterator<long>::_Node:
Python Exception <type 'exceptions.ValueError'> Cannot find type std::_List_const_iterator<long>::_Node:
#1  0x0000000000402c6b in std::__distance<std::_List_const_iterator<long> > (__first=, __last=) at /usr/include/c++/4.8.2/bits/stl_iterator_base_funcs.h:82
Python Exception <type 'exceptions.ValueError'> Cannot find type std::_List_const_iterator<long>::_Node:
Python Exception <type 'exceptions.ValueError'> Cannot find type std::_List_const_iterator<long>::_Node:
#2  0x0000000000402386 in std::distance<std::_List_const_iterator<long> > (__first=, __last=) at /usr/include/c++/4.8.2/bits/stl_iterator_base_funcs.h:118
#3  0x0000000000401d31 in std::list<long, std::allocator<long> >::size (this=0x606430 <table3>) at /usr/include/c++/4.8.2/bits/stl_list.h:874
#4  0x0000000000401295 in customer (vargp=0xd) at project2.cc:129
#5  0x00002aaaab4f6ea5 in start_thread () from /lib64/libpthread.so.0
#6  0x00002aaaab8099fd in clone () from /lib64/libc.so.6

由此,我很确定我的问题在于 remove() 函数,但我不知道如何解决它。有人对此有解决方案吗?

标签: c++concurrencypthreads

解决方案


当另一个线程正在或可能正在访问它时,切勿修改一个线程中的对象,除非您使用的是专门记录的对象以允许该类型的并发性。


推荐阅读