1 // Copyright (C) 2010 Vicente Botet 2 // 3 // Distributed under the Boost Software License, Version 1.0. (See accompanying 4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5 6 #define BOOST_THREAD_VERSION 2 7 8 #include <boost/thread/thread.hpp> 9 #include <boost/thread/condition.hpp> 10 #include <boost/thread/recursive_mutex.hpp> 11 #include <list> 12 #include <iostream> 13 14 #if defined BOOST_THREAD_USES_CHRONO 15 16 using namespace std; 17 18 boost::recursive_mutex theMutex; 19 20 typedef std::list<boost::condition*> Conditions; 21 Conditions theConditions; 22 ThreadFuncWaiter()23void ThreadFuncWaiter() 24 { 25 boost::condition con1; 26 //for(; ; ) 27 for (int j = 0; j < 10; j++) 28 { 29 { 30 boost::unique_lock<boost::recursive_mutex> lockMtx(theMutex); 31 theConditions.push_back(&con1); 32 33 cout << "Added " << boost::this_thread::get_id() << " " << &con1 << endl; 34 if (con1.timed_wait(lockMtx, boost::posix_time::time_duration(0, 0, 50))) 35 { 36 cout << "Woke Up " << boost::this_thread::get_id() << " " << &con1 << endl; 37 } 38 else 39 { 40 cout << "*****Timed Out " << boost::this_thread::get_id() << " " << &con1 << endl; 41 exit(13); 42 } 43 44 theConditions.remove(&con1); 45 cout << "Removed " << boost::this_thread::get_id() << " " << &con1 << endl; 46 cout << "Waiter " << j << endl; 47 48 } 49 //Sleep(2000); 50 boost::this_thread::sleep_for(boost::chrono::milliseconds(200)); 51 } 52 } 53 ThreadFuncNotifier()54void ThreadFuncNotifier() 55 { 56 for (int j = 0; j < 70; j++) 57 { 58 { 59 boost::unique_lock<boost::recursive_mutex> lockMtx(theMutex); 60 cout << "<Notifier " << j << endl; 61 62 unsigned int i = 0; 63 for (Conditions::iterator it = theConditions.begin(); it != theConditions.end() && i < 2; ++it) 64 { 65 (*it)->notify_one(); 66 //WORKAROUND_ lockMtx.unlock(); 67 //WORKAROUND_ boost::this_thread::sleep_for(boost::chrono::milliseconds(50)); 68 cout << "Notified One " << theConditions.size() << " " << (*it) << endl; 69 ++i; 70 //WORKAROUND_ lockMtx.lock(); 71 } 72 73 cout << "Notifier> " << j << endl; 74 } 75 boost::this_thread::sleep_for(boost::chrono::milliseconds(50)); 76 } 77 } 78 main()79int main() 80 { 81 boost::thread_group tg; 82 for (int i = 0; i < 12; ++i) 83 { 84 tg.create_thread(ThreadFuncWaiter); 85 } 86 87 tg.create_thread(ThreadFuncNotifier); 88 89 tg.join_all(); 90 91 return 0; 92 } 93 94 95 #else 96 #error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" 97 #endif 98