下面先对condition_impl进行简要分析。
condition_impl在其构造函数中会创建两个Semaphore(信号量):m_gate、m_queue,及一个Mutex(互斥体,跟boost ::mutex类似,但boost ::mutex是基于CriticalSection <临界区 >的):m_mutex,其中:
m_queue
相当于当前所有等待线程的等待队列,构造函数中调用CreateSemaphore来创建Semaphore时,lMaximumCount参数被指定为 (std ::numeric_limits < long >::max )(),即便如此,condition的实现者为了防止出现大量等待线程的情况(以至于超过了 long的最大值),在线程因执行condition ::wait进入等待状态时会先:
WaitForSingleObject ( reinterpret_cast <HANDLE >(m_queue ), INFINITE );
以等待被唤醒,但很难想象什么样的应用需要处理这么多线程。
m_mutex
用于内部同步的控制。
但对于m_gate我很奇怪,我仔细研究了一下condition_imp的实现,还是不明白作者引入m_gate这个变量的用意何在,既然已经有了用于同步控制的m_mutex,再引入一个m_gate实在让我有点不解。

以下是condition ::wait调用的do_wait方法简化后的代码:

1  template  < typename M >
2  void  do_wait(M &  mutex)
3  {
4      m_impl.enter_wait();
5      lock_ops::unlock(mutex, state);     // 对传入的scoped_lock对象解锁,以便别的线程可以对其进行加锁,并执行某些处理,否则,本线程等待的condition永远不会发生(因为没有线程可以获得访问资源的权利以使condition发生)
6      m_impl.do_wait();     // 执行等待操作,等待其它线程执行notify_one或notify_all操作以获得
7      lock_ops::lock(mutex, state);     // 重新对scoped_lock对象加锁,获得独占访问资源的权利
8  }
condition ::timed_wait的实现方法与此类似,而notify_one、notify_all仅将调用请求转发给m_impl,就不多讲了。

虽然condition的内部实现比较复杂,但使用起来还是比较方便的。下面是一个使用condition的多Producer -多Consumer同步的例子:
  1  #include  < boost / thread / thread.hpp >
  2  #include  < boost / thread / mutex.hpp >
  3  #include  < boost / thread / condition.hpp >
  4  #include  < boost / thread / xtime.hpp >
  5 
  6  #include  < iostream >
  7  #include  < time.h >   //  for time()
  8 
  9  #include  < Windows.h >      //  for Sleep, change it for other platform, we can use
 10                           //  boost::thread::sleep, but it's too inconvenient.
 11 
 12  typedef boost::mutex::scoped_lock scoped_lock;
 13  boost::mutex io_mutex;
 14 
 15  class  Product
 16  {
 17       int  num;
 18  public :
 19      Product( int  num) : num(num) {}
 20 
 21      friend std::ostream &  operator <<  (std::ostream &  os, Product &  product)
 22      {
 23           return  os  <<  product.num;
 24      }
 25  };
 26 
 27  class  Mediator
 28  {
 29  private :
 30      boost::condition cond;
 31      boost::mutex mutex;
 32 
 33      Product **  pSlot;     //  product buffer/slot
 34      unsigned  int  slotCount,     //  buffer size
 35          productCount;  //  current product count
 36      bool stopFlag;     //  should all thread stop or not
 37 
 38  public :
 39      Mediator( const   int  slotCount) : slotCount(slotCount), stopFlag( false ), productCount( 0 )
 40      {
 41          pSlot  =   new  Product * [slotCount];
 42      }
 43 
 44      virtual  ~ Mediator()
 45      {
 46           for  ( int  i  =   0 ; i  <  static_cast < int > (productCount); i ++ )
 47          {
 48              delete pSlot[i];
 49          }
 50          delete [] pSlot;
 51      }
 52 
 53      bool Stop()  const  {  return  stopFlag; }
 54       void  Stop(bool) { stopFlag  =   true ; }
 55 
 56       void  NotifyAll()     //  notify all blocked thread to exit
 57      {
 58          cond.notify_all();
 59      }
 60 
 61      bool Put( Product *  pProduct)
 62      {
 63          scoped_lock lock(mutex);
 64           if  (productCount  ==  slotCount)
 65          {
 66              {
 67                  scoped_lock lock(io_mutex);
 68                  std::cout  <<   " Buffer is full. Waiting "   <<  std::endl;
 69              }
 70               while  ( ! stopFlag  &&  (productCount  ==  slotCount))
 71                  cond.wait(lock);
 72          }
 73           if  (stopFlag)  //  it may be notified by main thread to quit.
 74               return   false ;
 75 
 76          pSlot[ productCount ++  ]  =  pProduct;
 77          cond.notify_one();     //  this call may cause *pProduct to be changed if it wakes up a consumer
 78 
 79           return   true ;
 80      }
 81 
 82      bool Get(Product **  ppProduct)
 83      {
 84          scoped_lock lock(mutex);
 85           if  (productCount  ==   0 )
 86          {
 87              {
 88                  scoped_lock lock(io_mutex);
 89                  std::cout  <<   " Buffer is empty. Waiting "   <<  std::endl;
 90              }
 91               while  ( ! stopFlag  &&  (productCount  ==   0 ))
 92                  cond.wait(lock);
 93          }
 94           if  (stopFlag)  //  it may be notified by main thread to quit.
 95          {
 96               * ppProduct  =  NULL;
 97               return   false ;
 98          }
 99 
100           * ppProduct  =  pSlot[ -- productCount];
101          cond.notify_one();
102 
103           return   true ;
104      }
105  };
106 
107  class  Producer
108  {
109  private :
110      Mediator *  pMediator;
111       static  unsigned  int  num;
112      unsigned  int  id;     //  Producer id
113 
114  public :
115      Producer(Mediator *  pMediator) : pMediator(pMediator) { id  =  num ++ ; }
116 
117       void  operator() ()
118      {
119          Product *  pProduct;
120          srand( (unsigned)time( NULL )  +  id );     //  each thread need to srand differently
121           while  ( ! pMediator -> Stop())
122          {
123              pProduct  =   new  Product( rand()  %   100  );
124               //  must print product info before call Put, as Put may wake up a consumer
125               //  and cause *pProuct to be changed
126              {
127                  scoped_lock lock(io_mutex);
128                  std::cout  <<   " Producer[ "   <<  id  <<   " ] produces Product[ "
129                       <<   * pProduct  <<   " ] "   <<  std::endl;
130              }
131               if  ( ! pMediator -> Put(pProduct))     //  this function only fails when it is notified by main thread to exit
132                  delete pProduct;
133 
134              Sleep( 100 );
135          }
136      }
137  };
138 
139  unsigned  int  Producer::num  =   1 ;
140 
141  class  Consumer
142  {
143  private :
144      Mediator *  pMediator;
145       static  unsigned  int  num;
146      unsigned  int  id;     //  Consumer id
147 
148  public :
149      Consumer(Mediator *  pMediator) : pMediator(pMediator) { id  =  num ++ ; }
150 
151       void  operator() ()
152      {
153          Product *  pProduct  =  NULL;
154           while  ( ! pMediator -> Stop())
155          {
156               if  (pMediator -> Get( & pProduct))
157              {
158                  scoped_lock lock(io_mutex);
159                  std::cout  <<   " Consumer[ "   <<  id  <<   " ] is consuming Product[ "
160                       <<   * pProduct  <<   " ] "   <<  std::endl;
161                  delete pProduct;
162              }
163 
164              Sleep( 100 );
165          }
166      }
167  };
168 
169  unsigned  int  Consumer::num  =   1 ;
170 
171  int  main()
172  {
173      Mediator mediator( 2 );     //  we have only 2 slot to put products
174 
175       //  we have 2 producers
176      Producer producer1( & mediator);
177      boost::thread thrd1(producer1);
178      Producer producer2( & mediator);
179      boost::thread thrd2(producer2);
180       //  and we have 3 consumers
181      Consumer consumer1( & mediator);
182      boost::thread thrd3(consumer1);
183      Consumer consumer2( & mediator);
184      boost::thread thrd4(consumer2);
185      Consumer consumer3( & mediator);
186      boost::thread thrd5(consumer3);
187 
188       //  wait 1 second
189      Sleep( 1000 );
190       //  and then try to stop all threads
191      mediator.Stop( true );
192      mediator.NotifyAll();
193 
194       //  wait for all threads to exit
195      thrd1.join();
196      thrd2.join();
197      thrd3.join();
198      thrd4.join();
199      thrd5.join();
200 
201       return   0 ;
202  }