How to know wheter a Boost.thread has ended ?
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()) { ... } } How can I do such a thing, any ideas? Thanks, Simon _________________________________________________________________ MSN Search, le moteur de recherche qui pense comme vous ! http://fr.ca.search.msn.com/
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<threadworker*>(handle.body); } threadworker() : handle( new worker ) { } threadworker( const threadworker& rkOther ) : handle( rkOther ) { } void operator() { pbodyWorker()->doWork(); } bool isDone() { return pbodyWorker()->isDone(); } private: // disallow this one threadworker& operator=( const threadworker& ); }; There's probably a more "boosty" way to create handles than this, but since I've got the infrastructure and it's a very common pattern in my code base (written LONG before boost and STL came along), it fits for me. Anyway, now you've got your asynchronous isDone() check and you're checking the same object that the thread is running, not a copy of it. HTH (much longer than I intended), - Mark
participants (2)
-
Huck finn
-
Mark Sizer