problems with STL list in a multithreaded environment

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • vmpstr
    New Member
    • Nov 2008
    • 63

    problems with STL list in a multithreaded environment

    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.
  • weaknessforcats
    Recognized Expert Expert
    • Mar 2007
    • 9214

    #2
    Changing the structure of an STL container invalidates existing iterators. Are you certain you are not using an un-refreshed iterator?

    Comment

    • vmpstr
      New Member
      • Nov 2008
      • 63

      #3
      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

      Comment

      • weaknessforcats
        Recognized Expert Expert
        • Mar 2007
        • 9214

        #4
        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.

        Comment

        • vmpstr
          New Member
          • Nov 2008
          • 63

          #5
          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.

          Comment

          Working...