Huck finn wrote:
Hi, I need a way to find out if the threads that I created are done or not. I'm creating a somekind of thread_group that must clean the threads that have ended from the vector that keeps the threads within.
void function () {}
void main () { boost::thread thrd1(&function);
//I'd need a function here to tell me that the thread has ended... if(thread1.IsDone()) { ... } }
Unless your thread does something VERY short, that's probably not what
you want anyway. It would look more like:
int main() // note the "int"
{
boost::thread thread1(&function); // note variable names match now
while ( true )
{
if ( thread1.IsDone() )
{
// cleanup
break;
}
}
}
In which case you can do this:
int main()
{
boost::thread thread1(&function );
thread1.join();
// won't get here until the thread ends
}
This, of course, has the obvious problem of blocking until the thread is
complete. Sometimes that's a good thing; sometimes not.
My solution:
class worker
{
public:
worker() :
_mutexDone(),
_bDone(false) // in most cases this is race condition safe
// but not all, you may have to lock it
{
}
bool isDone() const
{
boost::mutex::scoped_lock lockDone(_mutexDone);
return _bDone;
}
void doWork()
{
// do whatever
markDone();
}
private:
void markDone()
{
boost::mutex::scoped_lock lockDone(_mutexDene);
_bDone = true;
}
mutable boost::mutex _mutexDone;
bool _bDone;
};
You get the idea. You can create a graceful shutdown interface with
another pair of methods with the public/private reversed (public to set
the shutdown flag, private to check it).
Now, the problem is that this will get copied if you try to use it
directly, which is why there is no operator(). You'll need to wrap this
in some sort of handle class with the appropriate operators. I happen to
have one handy that I just re-use.
The important bit is to make sure copying is OK and add the operator()
calls worker::doWork(). Assuming a handle class that does reference
counting, etc..
class threadworker : public handle
{
public:
threadworker* pbodyWorker() const
{
assert( handle.body != NULL );
return dynamic_cast