C++从多线程访问向量

8ljdwjyq  于 2023-01-06  发布在  其他
关注(0)|答案(3)|浏览(190)

在我的程序中,我有一些线程在运行,每个线程都有一个指向某个对象(在我的程序中是vector)的指针,每个线程都修改这个向量。
有时候我的程序会因为segm-fault而失败,我认为这是因为线程A开始处理向量,而线程B还没有处理完,这是真的吗?
我应该怎么修复它?线程同步?或者可能做一个标志VectorIsInUse并在使用它操作时将此标志设置为true?

cngwdvgl

cngwdvgl1#

vector和所有STL容器一样,不是线程安全的。你必须自己显式地管理同步。std::mutexboost::mutex可以用来同步对vector的访问。
不要使用标志,因为这不是线程安全的:

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

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

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

// 'i' can become invalid if the `vector` is modified.
rkkpypqq

rkkpypqq2#

如果你想让一个容器在多个线程中安全使用,你需要使用一个明确为此目的设计的容器。标准容器的接口不是为并发变异或任何类型的并发而设计的,你不能只是在问题上抛出一个锁。
你需要像TBB或PPL这样的东西,里面有concurrent_vector

ckx4rj1h

ckx4rj1h3#

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

相关问题