在我的程序中,我有一些线程在运行,每个线程都有一个指向某个对象(在我的程序中是vector)的指针,每个线程都修改这个向量。有时候我的程序会因为segm-fault而失败,我认为这是因为线程A开始处理向量,而线程B还没有处理完,这是真的吗?我应该怎么修复它?线程同步?或者可能做一个标志VectorIsInUse并在使用它操作时将此标志设置为true?
VectorIsInUse
cngwdvgl1#
vector和所有STL容器一样,不是线程安全的。你必须自己显式地管理同步。std::mutex或boost::mutex可以用来同步对vector的访问。不要使用标志,因为这不是线程安全的:
vector
std::mutex
boost::mutex
isInUse
false
true
请注意,每个线程在使用vector的整个时间内都必须锁定它。这包括修改vector和使用vector的迭代器,因为如果它们引用的元素是erase()或vector经历内部重新分配,则迭代器可能会失效。例如do not:
erase()
mtx.lock(); std::vector<std::string>::iterator i = the_vector.begin(); mtx.unlock(); // 'i' can become invalid if the `vector` is modified.
rkkpypqq2#
如果你想让一个容器在多个线程中安全使用,你需要使用一个明确为此目的设计的容器。标准容器的接口不是为并发变异或任何类型的并发而设计的,你不能只是在问题上抛出一个锁。你需要像TBB或PPL这样的东西,里面有concurrent_vector。
concurrent_vector
ckx4rj1h3#
这就是为什么几乎每个提供线程的类库都有同步原语,比如互斥锁/锁,你需要设置其中的一个,并在共享项的每个操作(读和写操作,因为你需要防止写操作的同时发生读操作,而不仅仅是防止多个写操作并发发生)周围获取/释放锁。
3条答案
按热度按时间cngwdvgl1#
vector
和所有STL容器一样,不是线程安全的。你必须自己显式地管理同步。std::mutex
或boost::mutex
可以用来同步对vector
的访问。不要使用标志,因为这不是线程安全的:
isInUse
标志的值,它是false
isInUse
标志的值,结果为false
isInUse
设置为true
isInUse
是false
,并将其设置为true
vector
请注意,每个线程在使用
vector
的整个时间内都必须锁定它。这包括修改vector
和使用vector
的迭代器,因为如果它们引用的元素是erase()
或vector
经历内部重新分配,则迭代器可能会失效。例如do not:rkkpypqq2#
如果你想让一个容器在多个线程中安全使用,你需要使用一个明确为此目的设计的容器。标准容器的接口不是为并发变异或任何类型的并发而设计的,你不能只是在问题上抛出一个锁。
你需要像TBB或PPL这样的东西,里面有
concurrent_vector
。ckx4rj1h3#
这就是为什么几乎每个提供线程的类库都有同步原语,比如互斥锁/锁,你需要设置其中的一个,并在共享项的每个操作(读和写操作,因为你需要防止写操作的同时发生读操作,而不仅仅是防止多个写操作并发发生)周围获取/释放锁。