是否可以使用互斥锁来锁定向量中的元素而不是整个向量?

时间:2011-10-30 00:07:57

标签: c++ multithreading vector mutex deadlock

是否可以使用互斥锁来锁定向量中的元素而不是整个向量?

例如,给定一个向量myVec;      将10个元素推回myVec

  for (int i = 0; i < 10; ++i)
  {
          buffer myBuf = i; // actually myBuf is not necessarily int.
          myVec.push_back(myBuf);
  }

向量的每个元素将由多个线程异步更改。 如何使用互斥锁只锁定myVec中的一个缓冲区,以便一个线程可以写入或读取一个元素;另一个可以同时读写另一个元素吗?

感谢

2 个答案:

答案 0 :(得分:4)

你想要的比你想象的更简单也更困难:

如果您的容器整体没有变化,即没有插入或删除,那么标准库容器已经提供了有限类型的线程安全性,即允许不同的线程读取或修改不同< / em>容器元素,即只要不超过一个线程访问任何给定元素。

另一方面,如果容器被整体修改,那么你几乎没有任何安全性:根据容器的类型,你绝对必须理解引用和迭代器失效。 如果您知道元素的引用或迭代器不受影响,则上述内容适用(分别适用于引用或取消引用的迭代器)。如果没有,那么除了重新获得对所需元素的新引用之外,你没有其他任何希望。

答案 1 :(得分:2)

如果向量在启动时初始化,它就像一个固定大小的数组,因此不需要锁定它。 我希望在那一点上有一个数组:)如果你想要的话,用new []分配。

如果,假设,threadN只访问fieldN,则不需要任何锁定,当多个线程尝试访问以进行读取和写入相同的资源时,需要锁定。

如果一个线程只访问一个资源进行读写,并且该资源不被任何其他线程访问,那么绝对没有问题!你不需要任何锁定。

如果仅在只读模式下在多个线程之间访问一个资源,则不需要任何锁定。

如果不清楚,在您的情况下,array[i]是读/写资源,而array是共享的只读资源。

如果需要同步每个元素,则需要为每个元素使用互斥锁。 如果有m个线程访问n个资源,则需要使用n个互斥锁来锁定资源。它们并不贵。

如果您拥有太多资源,则可以锁定阵列的某些部分:单个互斥锁将使您的应用程序成为单线程,但您可以为每10个项目分配1个互斥锁。通过这种方式,您可以减少互斥锁的数量,但同时确保不会将太多的线程停滞在一起。