同时读取和写入向量会导致异常

Tom*_*Tom 0 c++ windows multithreading boost vector

我在Windows上有2个线程(使用boost线程库)和全局向量(visual studio 2005).我创建了线程 - 首先是读取文件(vector.push_back(value))并增加"读取计数器",另一个是处理已经加载的数据(第二个"指针"记住已经处理的向量中的索引).处理就像vector[i] = function(vector[i]);

当我启动程序时,它最终会出现异常Unhandled exception at 0x0041350c in program.exe: 0xC0000005: Access violation writing location 0x00b82214.读取计数器的值小于记录计数(仍在读取文件),vector.size()是"readCounter + 1","处理指针"+/- 2200(远不如此)读取计数器 - 读取空值没问题)...每次运行的值都不同(有时,没有抛出异常,程序结束)......

当我删除处理行(vector[i] = function(vector[i]);)没有问题发生...所以我猜,矢量不是线程安全的.你能帮助我,如何预防这个问题?

Mat*_*lia 6

当前版本的标准(C++ 03)甚至不是线程感知的,因此STL容器是否是线程安全的事实完全取决于特定的实现.

在您的情况下,您应该参考MSDN的这一页,其中说明了这一点

单个对象对于从多个线程读取是线程安全的.例如,给定对象A,可以安全地从线程1和线程2同时读取A.

如果一个线程正在写入单个对象,则必须保护对相同或其他线程上该对象的所有读写操作.例如,给定对象A,如果线程1写入A,则必须阻止线程2读取或写入A.

因此,您必须使用互斥锁或其他同步原语来保护读/写.您可以在Boost.Thread中找到多平台和C++友好的实现(顺便说一下,C++ 0x中的线程支持所基于的库).


顺便说一下,如果您曾经使用过VC++的早期版本(例如2003),请记住在这些版本中,标准库的多线程和单线程版本都可用.如果在应用程序中使用线程和CRT工具,则不应使用CRT的单线程版本,请务必检查项目设置以查看是否选择了正确的版本.