【问题标题】:What can two threads/objects do in a collection of objects safely in C++?在 C++ 中,两个线程/对象可以安全地在对象集合中做什么?
【发布时间】:2015-05-23 02:12:50
【问题描述】:

因此,在我开始编写应该与属于集合的多个对象进行交互的多线程程序之前......我想清楚地了解所涉及的概念......

我主要担心死锁之类的事情。

假设我有一个这样定义的对象集合......

vector<MyObjects> m_objects;

想象一下它被填充了 100-500 个对象。 现在想象一下,这些对象中的每一个都需要在某个时候与所有其他对象进行通信。用英语来说,他们需要能够安全地读取和写入所有其他对象......

我知道为了写入一个对象,它需要被锁定......但是一个对象可以在没有额外功能的情况下安全地从另一个对象读取吗?如果是这样,对象可以从正在写入的锁定对象中读取吗? (我对最后一个问题的第一个猜测是否定的,因为这没有意义)

如果有人对此主题有一些易于理解的文章/读物,我很乐意深入研究一下...

【问题讨论】:

  • 我不确定你想要什么。 “现在想象......在某个时候其他对象”......还有什么其他对象? Vector 中的其他对象?
  • 是向量中的其他对象。
  • 问题是 - 矢量是否会改变。如果vector没有变化,vector本身就不需要被保护。一般来说,多次读取是安全的,读/写和多次写入是不安全的。您还会遇到“错误共享”的问题,即对象可以在缓存中彼此靠近,从而导致不必要的缓存抖动。
  • OK,向量本身可以修改吗?它的大小是否可以增长,是否可以在运行时删除项目,等等。
  • 向量的内容会不断变化,向量中对象的添加和删除也会发生。

标签: c++ multithreading


【解决方案1】:

您必须锁定对象内的共享资源。每个对象都应在其中保持其开启状态,如果该状态不是系统共享资源的一部分,则无需锁定它们。

【讨论】:

    【解决方案2】:

    最安全的解决方案是锁定整个向量,因此一次只有一个线程可以修改向量及其包含的对象。但是,问题是,如果多线程仍然有意义,那么......

    试图用自己的锁保护向量中的每个对象很容易导致循环依赖,并且有潜在的危险。

    想象以下场景,使用上面 cmets 中的 Boxer 比喻:

    Boxer1 试图击中 Boxer2。如果出拳的影响取决于 Boxer1 当前的健康水平,则您必须先锁定 Boxer1,因为您不希望任何人在执行出拳操作时改变他的健康状况。同时,您必须锁定 Boxer2,因为您不希望任何人在 Boxer1 的出击期间增加他的生命值(也许 Boxer1 会将 Boxer2 击倒......)。

    现在,如果 Boxer2 尝试击中 Boxer2 同时尝试击中 Boxer1,您也将先锁定 Boxer2,然后再锁定 Boxer1。

    因此,如果对您的拳击手执行操作的两个线程同时到达他们锁定自己拳击手的部分,他们将永远等待锁定另一个拳击手,您将陷入死锁。

    为了防止这种死锁,您必须制定某种锁定层次结构。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多