多线程读取和写入:: stl :: vector,难以释放矢量资源

时间:2008-11-06 10:00:56

标签: multithreading stl

我正在使用STL在VS2005中编写代码。 我有一个用于读取向量的UI线程,以及一个用于写入向量的工作线程。 我使用:: boost :: shared_ptr作为向量元素。

vector<shared_ptr<Class>> vec;

但我发现,如果我在同一时间操纵两个线程中的vec(我可以保证它们不访问同一区域,UI线程总是读取有信息的区域)

vec.clear()似乎无法释放资源。在shared_ptr中发生问题,它无法释放其资源。

有什么问题? 是因为当向量达到其订单容量时,它会在内存中重新分配,然后原始部分无效。

据我所知,在重新分配时,迭代器将无效,为什么当我使用vec [i]时也会发生一些问题。 // ----------------------------------------------- < / p>

需要什么样的锁? 我的意思是:如果向量的元素是shared_ptr,当线程A得到点smart_p时,另一个线程B将等待直到A完成对smart_p的操作吗? 或者只是在线程尝试读取点时添加锁定,当读取操作完成时,线程B可以继续执行某些操作。

3 个答案:

答案 0 :(得分:4)

当您从多个线程访问相同的资源时,需要进行锁定。如果你不这样做,你会有各种奇怪的行为,就像你所看到的那样。

由于您正在使用Boost,因此使用锁定的一种简单方法是使用Boost.Thread库。您可以在此方案中使用的最佳锁类型是读取器/写入器锁;他们在Boost.Thread中被称为shared_mutex

但是,是的,由于线程之间缺乏同步,您所看到的本质上是未定义的行为。希望这有帮助!

编辑以回答OP的第二个问题:在向量中读取智能指针时应使用读取器锁定,在向向量写入或向向量添加项目时使用写入器锁定(因此,互斥锁仅用于向量) 。如果多个线程将访问指向对象(即智能指针指向的对象),则应为它们设置单独的锁。在这种情况下,最好还是在对象类中放置一个互斥对象。

答案 1 :(得分:0)

另一种方法是通过确保仅在一个线程中访问向量来完全消除锁定。例如,通过让工作线程向主线程发送一条消息,并将元素添加到向量中。

答案 2 :(得分:0)

可以同时访问像这样的列表或数组。但是,std :: vector因其调整大小行为而不是一个好的选择。要做到这一点,需要一个固定大小的数组,或者调整大小时的特殊锁定或复制更新行为。它还需要通过锁定或原子更新再次独立的前后指针。

另一个答案提到了消息队列。我所描述的共享数组是实现这些的共同数组。