Here's more or less the basic pattern I have set up for multithreading. I'm keeping things simple, so I'm just launching a thread to do a particular task, nothing clever. Class Worker is for a worker thread, based on some tutes from the net.
Code: Select all
class Worker
{
public:
Worker()
{
// the thread is not-a-thread until we call start()
m_IsRunning=false ;
m_NeedsJoin=false ;
}
void start(int N)
{
m_IsRunning=true ;
m_NeedsJoin=true ;
m_Thread = boost::thread(&Worker::processQueue, this, N);
}
void join()
{
m_Thread.join();
m_IsRunning=false ;
m_NeedsJoin=false ;
}
void processQueue(unsigned N)
{
float flVal=0.0f ;
for(UINT uNum=0 ; uNum<N ; uNum++)
flVal=sqrt((float)uNum) ;
m_IsRunning=false ;
}
bool IsRunning() { return m_IsRunning ; }
bool NeedsJoin() { return m_NeedsJoin ; }
private:
boost::thread m_Thread;
bool m_IsRunning ;
bool m_NeedsJoin ;
};
There are circumstances where, instead of calling Worker.join() and stalling until Worker was finished, I could instead check if worker is finished and, if not, skip joining until later on when it is finished. I looked at timed_join, but I don't think it does quite what I want. So I've tried the following.
I added the two m_IsRunning and m_NeedsJoin bools. The idea is that once Worker.start() is called, IsRunning and NeedsJoin become true. Once processQueue is finished, it sets IsRunning to false. So now the thread says that it isn't running but still needs a join.
At this point I can do my test. I check IsRunning, if true it means the thread hasn't finished yet so I skip doing a join. If IsRunning is false and NeedsJoin is true, it means the thread has finished but still needs a join, so I call Worker.Join(). At that point, IsRunning and NeedsJoin both become false.
Worker is the only one who can modify IsRunning and NeedsJoin.
So, that's my theory on how I can check if a thread is finished or not, and skip joining if it is still busy. It seems to work, but I know threading is a tricky business, and there could be some error to my logic, maybe some race condition or non-atomic problem.
Does this method look ok?
Edit: Or should I just call Worker.timed_join(0) and if false it means the thread was (past tense) still running at the moment I asked?