擦除和插入单个链表线程是否安全?

lat*_*des 4 c++ linked-list thread-safety singly-linked-list

使用std :: forward_list是否有删除插入时的数据竞争?例如,我有一个线程除了在列表的末尾添加新元素之外什么都不做,我有另一个线程可以遍历(相同)列表并可以从中删除元素.

根据我所知的链表,每个元素都有一个指向下一个元素的指针,所以如果我擦除最后一个元素,同时我插入一个新元素,这会导致数据竞争或者这些容器的工作方式不同(或他们是否处理这种可能性)?

如果是数据竞赛,是否有(简单而快速)的方法来避免这种情况?(注意:插入的线程是两者中最关键的速度.)

Die*_*ühl 6

标准C++库容器有线程安全保证,但它们往往不是人们会考虑线程安全保证的那种(也就是说,人们期待错误的错误).标准库容器的线程安全保证大致(相关部分17.6.5.9 [res.on.data.races]):

  1. 您可以根据需要拥有尽可能多的容器读者.究竟有哪些资格作为读者有点微妙但大致相当于const成员函数的用户加上使用一些非const成员只读取数据(读取数据的线程安全性不是任何容器关注的,即23.2. 2 [container.requirements.dataraces]指定可以在没有容器引入数据竞争的情况下更改元素.
  2. 如果有一个容器的编写器,则在另一个线程中不应该有其他读者或容器的写入.

也就是说,读取容器的一端并编写另一端并不是线程安全的!事实上,即使实际的容器更改不会立即影响读者,在将一段数据从一个线程传递到另一个线程时,总是需要某种形式的同步.也就是说,即使您可以保证消费者不是erase()生产者当前insert()的节点,也会有数据竞争.