• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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()23 void 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()54 void 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()79 int 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