Boost logo

Boost Users :

Subject: Re: [Boost-users] Race condition with Boost::Thread
From: Craig Henderson (cdm.henderson_at_[hidden])
Date: 2009-07-29 10:40:34


2009/7/29 Rob Yull <ryull_at_[hidden]>

> I’ve been writing a thread pool class as kind of an experiment with
> boost.threads, boost.bind, and boost.function. The code below is the worker
> thread, that will eventually pull jobs from a queue, execute them, then look
> and see if there is another job in the queue. I think I’ve got an
> interesting race condition. The problem I’m having is when the class goes
> out of scope. I’m getting an access violation from the run() member
> function (which is function being run by m_Thread). Right now, run() is
> just entering and leaving (no actual queue checking). By the time run() is
> getting executed, the class is starting to execute the destructor. I
> thought that having the join() call in the destructor should allow the
> thread to finish before the class data is destroyed. In Visual Studio
> 2005’s debugger, when it is getting to run(), it looks like the object has
> already been destroyed (this = 0x7fffffff), so the access violation is
> coming from the assignment to the m_Running member variable. If I take out
> the assignment, and run the debug, when it is entering run(), the this
> pointer is still showing as invalid, but the function completes and ends up
> back at the join() in the destructor, where the this pointer in the
> destructor is valid again. So as far as the destructor seems to be
> conserned, the class hasn’t been destroyed yet, but as far as the member
> class is, it has been destroyed already.
>
>
>
> If I do pad some instructions/time before the class goes out of scope,
> run() executes just fine (this pointer is valid). I have also tried moving
> the creation of m_Thread outside of the constructor to a separate member
> function call, but the result is the same.
>

The WorkerThread object is going out of scope before the run() is executed
in the secondary thread. You need to synchronise the startup/shutdown down.
I suggest you move the m_Running=true; into the run() [the thread isn't
running until run() is called, afterall], and in the dtor, wait for the
thread to start before calling join.

void run()
{
    BOOST_ASSERT(m_Running);
}

Regards
-- Craig



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net