多线程读写::stl::vector,向量资源难以释放

3

我正在使用VS2005编写代码,使用其STL功能。 我有一个UI线程用于读取向量,和一个工作线程用于向向量中写入数据。 我使用::boost::shared_ptr作为向量元素。

vector<shared_ptr<Class>> vec;

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

vec.clear()似乎无法释放资源。问题出现在shared_ptr上,它无法释放其资源。

问题是什么? 这是因为当向量达到其顺序容量时,它会重新分配内存,然后原始部分将无效。

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

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

3个回答

4

当您从多个线程访问同一资源时,锁定是必要的。如果不这样做,就会出现各种奇怪的行为,就像您看到的那样。

因为您正在使用 Boost,使用锁定的简单方法是使用 Boost.Thread 库。您可以在 Boost.Thread 中使用最好的锁定类型是读/写锁定;它们在 Boost.Thread 中称为 shared_mutex

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

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


0

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

另一个答案提到了消息队列。我描述的共享数组是实现这些的常见且有效的方法。


0
另一种选择是通过确保只有一个线程访问向量来完全消除锁定。例如,通过让工作线程向主线程发送包含要添加到向量中的元素的消息。

我差点就点赞你的回答了,只是可能楼主实际上想在这里实现一个消息队列。 :-P 不可否认,最好不要手动实现一个,但还是有可能的。 - C. K. Young

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接