
Hi there, at the end of this mail is a small program that starts three threads out of a fourth one ("thread4"). thread1, 2 and 3 are not allowed to start execution before a certain condition is met (here: go_ is set to true and the threads are notified of the changed condition). The threads increment a variable. Once this variable has reached a threshold (here: 10), execution is supposed to stop. This is done by calling the interrupt() function on each thread, which in turn catch the corresponding exception and act on it. All this seems to work nicely, except for the fact that the "master thread" (thread4 in this example) does not seem to get any processing time over a long period. Hence thread 1,2 and 3 count to a very high number before the stop condition is met. Here is the output of the program: Starting threads Going to sleep for 2 seconds in startAndStopThreads() Hello world Nr. 0 from thread 1 Hello world Nr. 1 from thread 2 [...] Hello world Nr. 6167 from thread 2 Hello world Nr. 6168 from thread 2 Sending interrupt Received interrupt in thread 3 Received interrupt in thread 1 Received interrupt in thread 2 Done ... Occasionally the counting can go on up to a few hundred thousand. This is on a single-processor machine with OpenSUSE 11/64 bit, g++ 4.3.1 and a recent trunk version of Boost 1.36 . The situation is much better on a four-processor system with the same operating system - the counter typically reaches only a few hundred there, presumably as thread4 gets access to a time slice more quickly (but why isn't it running permanently on a four processor machine - there are only 4 active threads ?). Is there anything that can be done to improve the time slices allocated to thread4 ? I am already calling the yield() function in thread1, 2 and 3. Thanks and Best Regards, Ruediger /*********************************************************************/ #include <iostream> #include <boost/cstdint.hpp> #include <boost/bind.hpp> #include <boost/exception.hpp> #include <boost/thread/mutex.hpp> #include <boost/thread/condition.hpp> #include <boost/thread/condition_variable.hpp> #include <boost/thread/thread.hpp> #include <boost/date_time.hpp> using namespace std; class test { public: test() :jointData_(0), MAXJOINTDATA(10), go_(false), thread1(boost::bind(&test::sayHello, this, 1)), thread2(boost::bind(&test::sayHello, this, 2)), thread3(boost::bind(&test::sayHello, this, 3)) { /* nothing */ } void startAndStopThreads(){ std::cout << "Going to sleep for 2 seconds in startAndStopThreads()" << std::endl; boost::this_thread::sleep(boost::posix_time::seconds(2)); boost::unique_lock<boost::mutex> lock(helloMutex_); go_=true; lock.unlock(); readyToGo_.notify_all(); while(true){ boost::unique_lock<boost::mutex> lock2(helloMutex_); if(jointData_ >= MAXJOINTDATA){ go_=false; std::cout << "Sending interrupt" << std::endl; thread1.interrupt(); thread2.interrupt(); thread3.interrupt(); break; } } thread1.join(); thread2.join(); thread3.join(); } void sayHello(const uint16_t threadNumber){ while(true){ boost::unique_lock<boost::mutex> lock(helloMutex_); while(!go_) { try{ readyToGo_.wait(lock); } catch(boost::thread_interrupted&){ std::cout << "Received interrupt in thread " << threadNumber << std::endl; return; } } std::cout << "Hello world Nr. " << jointData_++ << " from thread " << threadNumber << std::endl; boost::this_thread::yield(); } } private: volatile uint32_t jointData_; const uint32_t MAXJOINTDATA; bool go_; boost::mutex helloMutex_; boost::condition_variable readyToGo_; boost::thread thread1, thread2, thread3; }; main(){ test Test; std::cout << "Starting threads" << std::endl; // Test.startAndStopThreads(); // This doesn't make a difference boost::thread thread4(boost::bind(&test::startAndStopThreads,&Test)); thread4.join(); std::cout << "Done ..." << std::endl; }