Threading-Safe std:列出C++

Dar*_*ark 6 c++ multithreading mutex thread-safety

我是多线程新手,我试图简单地做一些std:列出线程安全.每当项目被添加或删除到列表时,是否足以执行mutex.lock()和mutex.unlock()?同样,我只是想让它们成为线程安全的.

谢谢

nat*_*ate 8

您必须保护对列表的所有访问权限才能安全.从没有锁定的列表中读取不会破坏列表,如果在另一个线程正在读取列表时修改列表,则任一线程都可能损坏(即崩溃或产生不正确的结果).

您必须为期望内容稳定的整个代码段保持锁定.如果另一个线程可以随时擦除或重新排序任何元素,那么这包括任何时候你有其内容的实时迭代器.如果对哪些线程可以操纵哪些元素存在限制,则可以放宽锁定要求以保持实时迭代器.

使用std :: lock_guard有助于确保正确管理锁定.只需在操作列表的任何范围的开头创建一个实例,并在范围的末尾它将自动解锁,即使范围通过异常退出.

  • 实际上,第二段是错误的。列表迭代器实际上是稳定的。不过,我看不到对这一段进行正确修改的琐碎内容。最好重写它。 (2认同)

Max*_*kin 3

请注意,C++ 没有定义线程安全,而是定义了数据竞争,这是当多个线程访问同一对象并且其中至少一个是写入者时发生的一种情况。

您可以使用互斥锁来消除std::list<>数据竞争的成员函数。您甚至可以使用 Bjarne Stroustrup 的 Wrapping C++ Member Function Calls 技术对任何任意对象执行此操作。这称为内部锁定,意味着对象维护自己的互斥体。

此方法不会使对对象内部状态的数据竞争无泄漏引用,例如引用、指针和迭代器。例如,当您迭代列表时,您不希望另一个线程通过删除元素来使迭代器无效,因此您必须保持互斥体锁定,直到迭代完成。

此外,在许多有用的场景中,需要以原子方式更改的不仅仅是一个对象。在这种情况下,您需要一个互斥体来序列化对多个对象的访问。