By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,502 Members | 1,620 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,502 IT Pros & Developers. It's quick & easy.

problems with STL list in a multithreaded environment

P: 63
Hi,

I am working on a multithreaded application, which also happens to use STL quite heavily.

I'm running into the following problem (I'm sorry I can't post any code, because it is quite large):

list A is accessed in several threads, all of which obtain a lock called lockA prior to reading from or writing to list A. There are other lists (B, C) and the code to access those obtains lockB and lockC respectively. When list B is modified, for example, lockB is obtained, but lockA and lockC aren't.

The problem I'm enountering is that stl's find(A.begin(), A.end(), someelement). It crashes once in a while (I can't reproduce this every time, but it does happen once a week or so, and the program runs 24/7).

GDB reveals that __first element is 0x10 in the
while (__first != __last && !(*__first == __val))
loop, in find's implementation (__first would be initialized to A.begin() and then increment until it reaches __last, which is initialized to A.end()).

Does anyone have any suggestions on how to proceed? What could be the problem? Just to reiterate, I'm sure proper locks are obtained for all accesses (I stared at this code for a better part of a day).

Any and all suggestions are appreciated, and thanks in advance.
Nov 18 '08 #1
Share this Question
Share on Google+
4 Replies


weaknessforcats
Expert Mod 5K+
P: 9,197
Changing the structure of an STL container invalidates existing iterators. Are you certain you are not using an un-refreshed iterator?
Nov 19 '08 #2

P: 63
I'm using

find(A.begin(), A.end(), someelement);

I assume A.begin()/A.end() get new iterators... The only way that I understand this would crash is that while find is executing, another thread changes the contents of A. However, the thread calling find has lockA acquired... The only way A is modified is if some other thread acquires lockA first, but it can't...

Am I correct in this? Can iterators pointing to object A be invalidated by using/changing iterators to object B? I hope not...

Thank you for the reply
Nov 19 '08 #3

weaknessforcats
Expert Mod 5K+
P: 9,197
Maybe. An object B iterator could be made to point to object A and delete it. In effect any iterator is capable of being used to alter the container structure and that will invalidate all other iterators regardless of locks.

From what you are encountering, it does look like some sort of race condition. Personally, rather than acquiring these locks I would be writing a Manager class that would enqueue those threads. The Manager would manage the STL container.

There wouldn't be any iterators to object A or object B. The Manager would return objects to the threads. The Manager would be the only mutator/deleter of objects in the list.
Nov 19 '08 #4

P: 63
Hmm...

I'll take a closer look at what is going on with other iterators (aside from the ones pointing to A). Sadly, this code is a part of a manager class that manages threads, and the lists are those of thread ids. Of course, for some reason multiple threads are executing in it...

Well, thank you for your help. I will post again if my investigation reveals anything surprising.
Nov 20 '08 #5

Post your reply

Sign in to post your reply or Sign up for a free account.