【问题标题】:C++ Using list.remove() causes a segmentation fault when used by multiple threadsC++ 使用 list.remove() 在多线程使用时会导致分段错误
【发布时间】:2021-12-13 04:06:46
【问题描述】:

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

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() 函数,但我不知道如何解决它。有人对此有解决方案吗?

【问题讨论】:

  • 标准容器并不意味着异步访问。您必须自己同步对列表的访问(插入和删除)。
  • 好的,谢谢。我不知道这个
  • Yksisarvinen 所说的大部分是真的。但值得注意的是,C++ 确实为并发访问容器元素提供了一些保证。特别是,对同一容器的不同元素的并发访问(读取或写入)始终是安全的,vector&lt;bool&gt; 除外(根据 22.2.2,N4861)。
  • vector&lt;bool&gt; 是如此的奇怪,以至于它通常是gets its own documentation page
  • 使用锁。如果您从多个线程访问容器,则类似于 std::mutex 或类似名称。

标签: c++ concurrency pthreads


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多