【问题标题】:Thread-safe communication between threads线程之间的线程安全通信
【发布时间】:2013-05-28 15:04:31
【问题描述】:

我正在为单线程应用程序(具有非线程安全 API)开发多线程插件。

我当前的插件有两个线程:主线程是应用程序的线程,另一个用于处理主线程的数据。长话短说,第一个创建对象,给它们一个 ID,将它们插入到地图中,有时甚至访问和删除它们(如果应用程序这么说的话);第二个是从该地图读取数据并更改对象。

我的问题是:我可以使用哪些技术来使我的插件线程安全?

【问题讨论】:

  • 是否允许主线程在工作线程处理对象时删除它?
  • 我会计算引用来访问单个对象(如果第一个线程没有改变它们)和一个互斥锁来保护地图(插入新项目)。计数引用在插入和第二个线程访问时增加,在删除和第二个线程完成其工作时减少。当计数引用达到 0 时,对象将(自动)删除自己。
  • 对于线程职责分离的程序,我喜欢使用非阻塞队列来传达作业和结果

标签: c++ c multithreading concurrency


【解决方案1】:

首先,您必须确定race conditions 可能存在的位置。然后,您将不得不使用某种机制来确保以安全的方式访问共享数据,从而实现Thread Safety

对于您的特定情况,竞争条件似乎将出现在共享映射上,并且可能还会出现在它包含的对象(映射值)上(如果两个线程可能同时尝试更改同一个对象)。

我的建议是您使用经过良好测试的线程安全映射实现,然后在需要时为映射值本身添加额外的“保护”。这样可以确保两个线程的映射始终处于一致状态,并且如果两个线程都尝试修改相同的对象数据(映射的值),则数据不会损坏或不一致。

对于映射本身,您可以搜索 C++ 的“并发哈希映射”或“原子哈希映射”数据结构,看看它们是否质量好并且可用于您的编译器/平台。很好的例子是英特尔的 TBB concurrent_hash_map 或 Facebook 的 folly AtomicHashMap。它们都有优点和缺点,您必须分析最适合您的情况。

对于映射包含的对象,您可以使用普通互斥锁(简单、锁定、修改数据、解锁)、原子操作(更复杂,仅适用于简单数据类型)或其他方法,这取决于您的编译器/平台和速度要求。

希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 2022-01-20
    • 1970-01-01
    • 2013-02-07
    • 1970-01-01
    • 2012-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多