Multithreading: Test if thread finished.

Get answers to all your basic programming questions. No Ogre questions, please!
User avatar
mkultra333
Gold Sponsor
Gold Sponsor
Posts: 1894
Joined: Sun Mar 08, 2009 5:25 am
x 116

Multithreading: Test if thread finished.

Post by mkultra333 »

I'm doing my first steps into multithreading. Using Boost::thread. Got the physics multithreaded, which is neat, but there's some other things I need to multithread as well.

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 ;
	

};  
So when Worker.start(N) is called, it launches processQueue in it's own thread. Later I call Worker.join() to synch up with the thread.

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?
"In theory there is no difference between practice and theory. In practice, there is." - Psychology Textbook.
User avatar
saejox
Goblin
Posts: 260
Joined: Tue Oct 25, 2011 1:07 am
x 36

Re: Multithreading: Test if thread finished.

Post by saejox »

Bool value would be a cached value in your method. So you can fetch an old cached value from your main thread.
In practice it is possible to get 'Worker thread is working', but thread is actually finished.

timed_join does what you described.
It will return true if thread is currently not working. ( returns true for zombie threads too)

Btw, one thread per task is such a waste of resources.
Nimet - Advanced Ogre3D Mesh/dotScene Viewer
asPEEK - Remote Angelscript debugger with html interface
ogreHTML - HTML5 user interfaces in Ogre
User avatar
mkultra333
Gold Sponsor
Gold Sponsor
Posts: 1894
Joined: Sun Mar 08, 2009 5:25 am
x 116

Re: Multithreading: Test if thread finished.

Post by mkultra333 »

Thanks. If it returns true, that also means I don't need to call Worker.join(), right?
Btw, one thread per task is such a waste of resources.
Maybe once I have half a clue what I'm doing, I'll try to be cleverer. The tasks in question scale to use as much CPU as available, so there shouldn't be much wasted CPU on at least those threads. Multithreading is kind of an experimental bonus at this stage, since I had things running fairly well when it was all just in a single thread.
"In theory there is no difference between practice and theory. In practice, there is." - Psychology Textbook.
User avatar
saejox
Goblin
Posts: 260
Joined: Tue Oct 25, 2011 1:07 am
x 36

Re: Multithreading: Test if thread finished.

Post by saejox »

.join's whole purpose is to make a thread wait for another thread to finish.
Nimet - Advanced Ogre3D Mesh/dotScene Viewer
asPEEK - Remote Angelscript debugger with html interface
ogreHTML - HTML5 user interfaces in Ogre
User avatar
spookyboo
Silver Sponsor
Silver Sponsor
Posts: 1141
Joined: Tue Jul 06, 2004 5:57 am
x 151

Re: Multithreading: Test if thread finished.

Post by spookyboo »

I am using boost::condition for this.
At the end of the function I call notify_one to indicate the function ends. Example can be found at http://www.paulbridger.com/condition_variables/
User avatar
mkultra333
Gold Sponsor
Gold Sponsor
Posts: 1894
Joined: Sun Mar 08, 2009 5:25 am
x 116

Re: Multithreading: Test if thread finished.

Post by mkultra333 »

Thanks spookyboo. Those tutorials look interesting too.
"In theory there is no difference between practice and theory. In practice, there is." - Psychology Textbook.