简体   繁体   English

在std :: list中没有锁定的并行追加和迭代

[英]Parallel append and iteration without locks in std::list

I am using a std::list in a multithreaded program. 我在多线程程序中使用std :: list。 Elements are only added to the end of the list and only removed from the beginning of the list. 元素仅添加到列表的末尾,并且仅从列表的开头除去。 There exists a writer lock to guarantee mutual exclusion for writes. 存在一个写程序锁,以确保相互排斥写操作。 Readers access the list without obtaining the lock. 读者无需获取锁即可访问列表。 The readers maintain iterators which cannot be invalidated by erase() as I guarantee that elements are only erased if the readers have passed them. 读者维护着迭代器,而这些迭代器不能被Erase()无效,因为我保证只有读者通过了这些元素后,它们才会被擦除。 The only possible data race I can imagine is if an element is appended, and one of the readers accesses that element before the inserter has written the element itself. 我能想象的唯一可能的数据竞争是是否添加了元素,并且其中一个读取器在插入程序编写元素本身之前访问了该元素。

With a single writer, appending (insert at the end) should be atomic as a single write is needed to insert the new element. 对于单个编写器,追加(末尾插入)应该是原子的,因为插入单个元素需要单次写入。

std::list apparently gives no guarantees whatsoever, can somebody confirm that above usage should work without data races. std :: list显然不提供任何保证,有人可以确认上述用法应该在没有数据争用的情况下起作用。 If not, is there an alternative (eg boost) which gives such a guarantee? 如果没有,是否有其他替代方法(例如,助推器)提供这种保证?

As you wrote, a race condition can happen: 如您所写,可能会发生竞争状况:

The only possible data race I can imagine is if an element is appended, and one of the readers accesses that element before the inserter has written the element itself. 我能想象的唯一可能的数据竞争是是否添加了元素,并且其中一个读取器在插入程序编写元素本身之前访问了该元素。

Also std::list is a doubly-linked list , so while removing the first element the second is accessed and while adding a new element the old last element is written to. 另外std :: list是一个双向链接的列表 ,因此在删除第一个元素时,第二个元素将被访问,而在添加新元素时,旧的最后一个元素将被写入。 So your iterators must be constant (no ++iter or --iter). 因此,您的迭代器必须是常量(没有++ iter或--iter)。

You may want to have a look at boost::lockfree::queue — it might be exactly what you are looking for. 您可能想看看boost :: lockfree :: queue -可能正是您想要的。

I used boost::intrusive::list which solves the problem when disabling the size counter, which became inconsistent when simultaneously removing and inserting elements. 我使用了boost :: intrusive :: list解决了禁用大小计数器时的问题,该问题在同时删除和插入元素时变得不一致。 Without this the boost list sets four pointers and nothing else when removing/inserting elements which is what I need. 没有这个,增强列表会设置四个指针,而在删除/插入元素时没有其他设置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM