在多线程应用程序中安全使用迭代器

时间:2015-10-27 11:21:23

标签: c++ multithreading iterator

假设我们有一个受锁保护的数据结构。

现在,Thread1执行这些语句(比如在功能块X中):

mGeoCodeVectorLock.lock();

auto it = std::find(mGeoCodeVector.begin(), mGeoCodeVector.end(), tokenName); 
if(it != mGeoCodeVector.end()) {        
         mGeoCodeVector.erase(it);        
}
mGeoCodeVectorLock.unlock();

然后Thread2执行这些语句(比如在另一个功能块Y中):

auto iter = std::find(mGeoCodeVector.begin(), mGeoCodeVector.end(), tokenName); 

    mGeoCodeVectorLock.lock();


    if(it != mGeoCodeVector.end()) {        
             mGeoCodeVector.erase(it);        
    }
    mGeoCodeVectorLock.unlock();

现在,我看到它的方式:

1)如果thread1获取了功能块X中的锁并设法擦除向量,那么,由于容器大小已经更改,已经持有迭代器并在功能块Y中等待锁定的线程最终会出现无效的迭代器by thread1。

2)因此,我想,解决这个问题的简单方法是,只有在设法锁定锁定后才能使用所有迭代器。

是否存在安全迭代器使用的一般原则/习惯用法,特别是关于多线程应用程序?

2 个答案:

答案 0 :(得分:4)

是。

  1. 锁定资源
  2. 创建迭代器
  3. 改变或查询资源
  4. 扔掉迭代器
  5. 解锁资源。
  6. 当然,在执行锁自动化1和5时使用RAII。

答案 1 :(得分:0)

你的结构是什么,它是真正的向量还是列表?如果它是一个向量,你必须在查找之前获取锁。但是,如果它是一个列表(或者可以作为列表),从列表中删除不会使除被删除对象之外的任何迭代器无效,因此只要令牌名称不同,就不需要锁定。