I know what the books say about std::deque being moderately thread safe but my experience is proving otherwise. I'm using VS 2010. There are at least two threads (could be N threads but adding threads only makes the problem happen sooner) each running the same code. Each thread contains the same code however a pointer to a unique instance of a struct that contains a deque is passed to each thread so in theory they each have their own deque to work with. However at varying times, I get errors when the threads try to access the deque (always a read). The deque is defined something like this:
struct A
{
deque<TAS*> dqTas;
}
TAS is a pointer to another struct.
Struct A is created as
A* Aptr = new A;
The TAS struct is also created the same way
TAS* pTas = new TAS
The errors are characterized by:
1) they happen at random times in the code. The threads may run for minutes processing data reading/writing to the deque before the error occurs.
2) More threads cause the problem to happen faster. The problem never happens with 1 thread.
3) Error msgs vary saying either the deque can't be dereferenced or the index is out of scope. If the deque can't dereference error occurs then the reason why from examining the data is completely undetectable. Everything looks in order, pointers, existing data in the deque, etc. If the problem is index out of range then somehow one or more data items (out of several hundred) suddenly get corrupted in the deque itself.
I've removed all deletes from every workflow pathway so that inadvertent deletion of memory can't be the issue.
The only thing it seems that could cause this is a global counter or pointer in the std::deque code. The character of these errors indicate a thread collision source. I've even verified that the addresses of each struct instance are different. In theory there should be zero chance of collisions since each thread has its own deque copy. The only way this happens with this setup is if the std::deque code has a global ptr or counter in it.
Has any one else had this experience? Would the boost deque functions perform better in such a scenario?
In case you'e wondering, this is the code that gpfs:
pTs->dqTas.push_front( pTb ); <<GPF happens after a write
#if defined (DEBUG)
long d2 = pTs->dqTas.size()-1;
if( d2 > 0 )
{
TASBAR* pDel2;
//pDel2 = pTs->dqTas[d2];
pDel2 = pTs->dqTas.at(d2); //<<GPF happens here
}
#endif
RESOLUTION:
Thank you all for your comments. The problem was resolved and it had nothing to do with the deque container. The random deque corruption was a symptom of the problem. The problem was caused by some old static variables declared locally in a function of a class that the thread instantiated. Those variables were being overwritten with addresses of other objects being saved in the same deque in another thread. I just got rid of those and everything started working as expected. As elementary as it may sound, the lesson here to remember is that static variables are essentially global variables (even if defined locally within a function), across threads. Probably best to avoid them altogether in any code that goes into threads that can run multiple instances of the same code, unless it's very clear why and how they're being used.