在我的程序中,我有一些线程正在运行。每个线程都有一个指向某个对象的指针(在我的程序中 - 向量)。每个线程都会修改向量。
有时我的程序会因段错误而失败。我认为它的发生是因为线程 A 开始对向量做一些事情,而线程 B 还没有完成对它的操作?这是真的吗?
我该如何解决?线程同步?或者也许制作一个标志VectorIsInUse
并在使用它时将此标志设置为true?
在我的程序中,我有一些线程正在运行。每个线程都有一个指向某个对象的指针(在我的程序中 - 向量)。每个线程都会修改向量。
有时我的程序会因段错误而失败。我认为它的发生是因为线程 A 开始对向量做一些事情,而线程 B 还没有完成对它的操作?这是真的吗?
我该如何解决?线程同步?或者也许制作一个标志VectorIsInUse
并在使用它时将此标志设置为true?
vector
与所有 STL 容器一样,不是线程安全的。您必须自己明确管理同步。A std::mutex
orboost::mutex
可用于同步对vector
.
不要使用标志,因为这不是线程安全的:
isInUse
标志的值,它是false
isInUse
标志的值,它是false
isInUse
为true
isInUse
是false
并设置它true
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.
如果您想要一个可以在多个线程中安全使用的容器,您需要使用专门为此目的设计的容器。标准容器的接口不是为并发变异或任何类型的并发而设计的,你不能只是在问题上加锁。
您需要其中包含 TBB 或 PPL 之类concurrent_vector
的东西。
这就是为什么几乎每个提供线程的类库都具有同步原语,例如互斥锁/锁。您需要设置其中一个,并获取/释放对共享项的每个操作的锁定(读取和写入操作,因为您也需要防止在写入期间发生读取,而不仅仅是防止同时发生多个写入)。