直观的线程安全

时间:2014-10-26 11:07:02

标签: c++ multithreading c++11 concurrency thread-safety

在我的3D游戏项目中尝试并发后,我开始怀疑是否有可能以直观,干净和隐含的方式实现线程安全。我不喜欢只是为了访问资源而显式锁定/解锁互斥锁 - 我更倾向于一个完全隐藏在实际工作的代码中的解决方案。在C ++ 11中是否有允许这样的设计模式或结构?

我想要实现这种情况的一个具体例子详述如下。

第1类:拥有一个共享资源(std::unordered_map),它将std::shared_ptr保存到第3类实例。该类访问这些共享资源。

第2类:有一个在它自己的线程中运行的函数。此函数访问Class 1中的共享资源(包括访问Class 3实例)。

第3类:两个线程都可以访问此类的函数。任何一个线程都可以读/写。

有什么建议吗?也许这里的真正问题更可能是我的设计使得线程安全不切实际?

1 个答案:

答案 0 :(得分:3)

有一些并发模式和习惯用法。无论多么通用,您都可以忘记所有同步与一个例外:不可变数据类型。如果没有任何东西写入某个值,那么线程就不需要同步它们的访问权限,因为如果某人正在写作,你只能数据竞争。

这包括参考计数。如果您在值类型中使用引用计数pimpl实现,则必须在构造和删除时写入引用计数。大多数情况下,这是通过原子操作完成的,这些操作比互斥锁或信号量更快,但可以带来自己的问题。

有复制/修改/交换。从不可变的共享值复制数据。修改副本。使用不可变值交换。留意ABA问题。

传递消息而不是使用共享数据。

最后(正如我能想到的那样)我们将共享值包装到一个对象中,该对象通过一些代理魔术为你完成大部分同步工作。 Facebook在其愚蠢的lib中发布了一个:https://github.com/facebook/folly/blob/master/folly/docs/Synchronized.md这可能会简化很多已经很简单的问题,但并不是一个全面的答案。