【发布时间】:2010-12-15 23:42:33
【问题描述】:
C++ 提供了非常方便的迭代遍历容器的方式,
for(vector<int>::const_iterator p = c.begin(); p!=c.end();p++){}
但如果正在发生这种情况,有人c.push_back(10)。
它会打破循环吗?
每次使用容器操作时都应该使用互斥锁吗?
谢谢。
【问题讨论】:
标签: c++ multithreading stl vector mutex
C++ 提供了非常方便的迭代遍历容器的方式,
for(vector<int>::const_iterator p = c.begin(); p!=c.end();p++){}
但如果正在发生这种情况,有人c.push_back(10)。
它会打破循环吗?
每次使用容器操作时都应该使用互斥锁吗?
谢谢。
【问题讨论】:
标签: c++ multithreading stl vector mutex
是的,这里有一个竞争条件。
如果您打算从多个线程中使用 STL 容器,并且其中至少一个线程可能会修改容器,则您需要同步对容器的访问。
最简单的方法是使用互斥体。
另一种选择是找到或实现一个线程安全的容器来提供您需要的功能。
【讨论】:
是的,当可以从其他线程写入时,您应该这样做。
http://www.sgi.com/tech/stl/thread_safety.html
如果多个线程访问单个容器,并且至少有一个线程可能写入,则用户负责确保容器访问期间线程之间的互斥。
【讨论】:
你有两个问题。首先,您有一个迭代器失效问题。因为push_back 增加了向量的大小,所以它有可能调用分配。每当向量的容量(不是元素数量)发生变化时,向量中的所有迭代器都会失效。这是最容易处理的,方法是确保在开始循环之前调用reserve(),以确保向量中有足够的空间来满足循环运行时所有未来的push_back 尝试。
另一个问题,如其他帖子中所述,当插入可能与正在访问的元素同时运行时,您会遇到竞争条件。
【讨论】:
是的,您需要使用互斥锁保护整个向量。这是不使用向量在线程之间共享数据的一个很好的理由。大多数时候我们使用队列,用锁来保护 push/pop。
如果您需要使用大缓冲区共享数据,我建议您使用某种带有“页面”的自定义结构,因此,您可以只阻塞一小部分,并让其他线程在内存的不同位置运行同一时间。
【讨论】:
最简单的方法是迭代前加锁,完成后解锁
【讨论】: