假设我们有一个受锁保护的数据结构。
现在,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)因此,我想,解决这个问题的简单方法是,只有在设法锁定锁定后才能使用所有迭代器。
是否存在安全迭代器使用的一般原则/习惯用法,特别是关于多线程应用程序?
答案 0 :(得分:4)
是。
当然,在执行锁自动化1和5时使用RAII。
答案 1 :(得分:0)
你的结构是什么,它是真正的向量还是列表?如果它是一个向量,你必须在查找之前获取锁。但是,如果它是一个列表(或者可以作为列表),从列表中删除不会使除被删除对象之外的任何迭代器无效,因此只要令牌名称不同,就不需要锁定。