tags:

views:

199

answers:

3

I am using a CList in a multithreaded environment and I keep having problem with the GetHead method. I have one thread that add data to the list, and an other thread who read and remove data from the list. Here is the reading part :

 value_type get_next()  
        {
          T t;
          if(!queue.IsEmpty()) {
             t = queue.GetHead();
          }
          return t;  //If the queue is empty we return an empty element
        }

Here is the inserting part :

 inline void insert(T &_in) 
        {
          queue.AddTail(_in);
        }

Here is the removing part

  inline void  pop_next()  
        {
          if(!queue.IsEmpty())  {
            queue.RemoveHead(); 
          }
        }

Why do I get a runtime error when I run this. It always fail at

t = queue.GetHead();

With this assertion :

template<class TYPE, class ARG_TYPE>
AFX_INLINE TYPE& CList<TYPE, ARG_TYPE>::GetHead()
    { ENSURE(m_pNodeHead != NULL);
     return m_pNodeHead->data; }

While the m_pNodeHead value is :

  • pNext 0x00000000 {pNext=??? pPrev=??? data={...} } CList > >,ATL::CStringT > > &>::CNode *
  • pPrev 0x00000000 {pNext=??? pPrev=??? data={...} } CList > >,ATL::CStringT > > &>::CNode *
  • data "" TESTSETSE ATL::CStringT > >
+4  A: 

You have a race condition between inserting and retrieving the value. Add a lock that includes the entire body of get_next(), insert(), and pop_next().

JSBangs
What bugs me is that when I switch to std::deque, it works realy fine, I only have to change the function (i.e. IsEmpty() to empty()).Why wouldn't CList work where std::deque does?
Drahakar
std::deque is not thread-safe either - the fact that you haven't hit a crash with std::deque is just due to luck, rather than any fundamental difference between std::deque and CList. As ever, just because something seems to work, it doesn't mean it's right...
DavidK
@DavidK "Just because something seems to work, it doesn't mean it's right" - I'm going to put that on my wall :)
Aidan Ryan
+2  A: 

CList is not thread safe - you'll need to use critical sections around those bits of code that check the status of the queue then do something with it.

Also, why do you have the bit that works with an item on the queue a different thread than the bit that removes items from the queue?

Michael Burr
A: 

Don't try to do GUI stuff in a non-GUI thread. Only one thread (typically) is the GUI thread. The thread with the message pump. In other words the main thread.

Your worker threads should send some kind of signal to the main thread, which then adds & removes items from the list box.

John Dibling