9

在我的程序中,我有一些线程正在运行。每个线程都有一个指向某个对象的指针(在我的程序中 - 向量)。每个线程都会修改向量。

有时我的程序会因段错误而失败。我认为它的发生是因为线程 A 开始对向量做一些事情,而线程 B 还没有完成对它的操作?这是真的吗?

我该如何解决?线程同步?或者也许制作一个标志VectorIsInUse并在使用它时将此标志设置为true?

4

3 回答 3

14

vector与所有 STL 容器一样,不是线程安全的。您必须自己明确管理同步。A std::mutexorboost::mutex可用于同步对vector.

不要使用标志,因为这不是线程安全的:

  • 线程 A 检查isInUse标志的值,它是false
  • 线程 A 被挂起
  • 线程 B 检查isInUse标志的值,它是false
  • 线程 B 设置isInUsetrue
  • 线程 B 被挂起
  • 线程 A 恢复
  • 线程 A 仍然认为isInUsefalse并设置它true
  • 线程 A 和线程 B 现在都可以访问vector

请注意,每个线程都必须在vector需要使用它的整个时间内锁定它。这包括修改vector和使用 的vector迭代器,因为如果迭代器引用的元素是erase()vector经历内部重新分配,迭代器可能会失效。例如不要

mtx.lock();
std::vector<std::string>::iterator i = the_vector.begin();
mtx.unlock();

// 'i' can become invalid if the `vector` is modified.
于 2012-09-04T10:02:01.520 回答
4

如果您想要一个可以在多个线程中安全使用的容器,您需要使用专门为此目的设计的容器。标准容器的接口不是为并发变异或任何类型的并发而设计的,你不能只是在问题上加锁。

您需要其中包含 TBB 或 PPL 之类concurrent_vector的东西。

于 2012-09-04T10:09:44.190 回答
1

这就是为什么几乎每个提供线程的类库都具有同步原语,例如互斥锁/锁。您需要设置其中一个,并获取/释放对共享项的每个操作的锁定(读取和写入操作,因为您也需要防止在写入期间发生读取,而不仅仅是防止同时发生多个写入)。

于 2012-09-04T09:58:26.763 回答