使用 std::forward_list 在删除和插入时是否存在数据竞争?例如,我有一个线程除了在列表末尾添加新元素外什么都不做,而我有另一个线程遍历(相同)列表并可以从中删除元素。
根据我对链表的了解,每个元素都包含一个指向下一个元素的指针,因此如果我删除最后一个元素,同时插入一个新元素,这会导致数据竞争还是执行这些操作容器的工作方式不同(或者它们是否处理这种可能性)?
如果是数据竞争,是否有一种(简单且快速)的方法来避免这种情况? (注意:插入的线程是两者中速度最关键的。)
最佳答案
标准 C++ 库容器有线程安全保证,但它们往往不是人们会考虑的线程安全保证类型(也就是说,然而,人们期望错误的错误)。标准库容器的线程安全保证大致如下(相关章节17.6.5.9 [res.on.data.races]):
- 您可以根据需要拥有任意数量的容器读者。 reader 的确切定义有点微妙,但大致相当于
const
的用户。成员函数加上使用一些非const
成员只读取数据(读取数据的线程安全不是容器关心的任何问题,即 23.2.2 [container.requirements.dataraces] 指定可以在容器不引入数据竞争的情况下更改元素)。 - 如果容器只有一个写入者,则在另一个线程中不应有其他容器的读取者或写入者。
也就是说,读取容器的一端并写入另一端是不是线程安全的!事实上,即使实际的容器更改不会立即影响读取器,在将一段数据从一个线程传送到另一个线程时,您总是需要某种形式的同步。也就是说,即使您可以保证消费者不会 erase()
当前生产者节点 insert()
s,会有一场数据竞赛。
关于c++ - 在单个链表线程中删除和插入是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20887412/