simultaneous reading and writing to vector cause exception
I have 2 threads (using开发者_Go百科 boost thread library) and global vector on Windows (visual studio 2005). I've created threads - first is reading file (vector.push_back(value)
) and increasing "read counter", another is processing data already loaded (second "pointer" remembers index in vector already processed). Processing is something like vector[i] = function(vector[i]);
When I start program, it ends up with an exception Unhandled exception at 0x0041350c in program.exe: 0xC0000005: Access violation writing location 0x00b82214.
Read counter has value less then records count (still reading the file), vector.size() is "readCounter + 1", "processing pointer" +/- 2200 (much less then read counter - no problem in reading empty value)... values are different each run (sometimes, no exception is thrown and program finishes)...
when I remove processing line (vector[i] = function(vector[i]);
) no problem occurs... so I guess, vector is not thread safe. Can you help me, how to prevent this problem?
The current version of the standard (C++03) isn't even thread-aware, so the fact that STL containers are thread-safe or not is completely up to the particular implementation.
In your case, you should refer to this page of MSDN, which states that
A single object is thread safe for reading from multiple threads. For example, given an object A, it is safe to read A from thread 1 and from thread 2 simultaneously.
If a single object is being written to by one thread, then all reads and writes to that object on the same or other threads must be protected. For example, given an object A, if thread 1 is writing to A, then thread 2 must be prevented from reading from or writing to A.
Thus, you must protect your read/writes with a mutex or some other synchronization primitive. You can find a multiplatform and C++-friendly implementation of them in Boost.Thread (which by the way is the library on which the threading support in C++0x is based).
By the way, if you ever had to use a previous version of VC++ (e.g. 2003), remember that in those versions there is both a multithread and a singlethread version of the standard library available. You should never use the singlethread version of the CRT if you use threads and CRT facilities in your application, always check in the project settings to see if the correct version is selected.
so I guess, vector is not thread safe.
Of course std::vector is not thread-safe (none of standard containers are guaranteed to be thread safe - but all their methods are guaranteed to be reentrant by every sane implementation). You have to use synchronization mechanisms (mutexes, etc.).
Vector is a growable data structure. Of course you cannot allocate arbitrary large memory so the implementation is allocating a fixed size memory (which you can set at construction time). As you push_back
elements into your vector it fills this space. When it reaches the end of the pre-allocated space it has to allocate a bigger chunk (usually double of the original size) and copy all the data in it. It also has to update the memory location where the chunk begins and free the old allocated space.
In the meantime you are trying to write some value to a memory address that doesn't belong to you anymore...
If you know how large it will grow you can pre-allocate all the memory it needs. This has the additional benefit that it doesn't have to copy it again and again as it doubles its size.
See: vector::vector, vector::capacity, vector::reserve
精彩评论