ACE_Condition类是针对OS条件变量原语的包装类。那么,到底什么是条件变量呢?
线程常常需要特定条件被满足才能继续它的操作。例如,设想线程需要在全局消息队列里插入消息。在插入任何消息之前,它必须检查在消息队列里是否有空闲空间。如果消息队列在“满”状态,它就什么也不能做,而必须进行休眠,过一会再重试。就是说,在访问全局资源之前,某个条件必须为真。然后,当另外的线程空出消息队列时,应该有方法通知或发信号给原来的线程:在消息队列里有位置了,现在应该再次尝试插入消息。这可以使用条件变量来完成。条件变量不是被用作互斥原语,而是用作特定条件已经满足的指示器。
在使用条件变量时,你的程序应该完成以下步骤:
获取全局资源(例如,消息队列)的锁(互斥体)。
检查条件(例如,消息队列里有空间吗?)。
如果条件失败,调用条件变量的wait()方法。等待在未来条件变为真。
当另一线程在全局资源上执行操作时,它发信号(signal())给所有其他在此资源上测试条件的线程(例如,另一线程从消息队列中取出一个消息,然后通过条件变量发送信号,以使阻塞在wait()上的线程能够再尝试将它们的消息插入队列)。
在醒来之后,重新检查条件现在是否为真。如为真,则在全局资源上执行操作(例如,将消息插入全局消息队列)
需要特别注意的是,[b]在阻塞在wait调用中之前,条件变量机制(也就是ACE_Cond)负责释放全局资源上的互斥体。如果没有进行此操作,将没有其他的线程能够在此资源上工作(该资源是条件改变的原因)。同样,一旦阻塞线程收到信号、重又醒来,它在检查条件之前会在内部重新获取锁。[/b]
用ACE_Thread::join()调用可以使主线程等待其他的线程结束。另一种达到同样目的的方法是使用条件变量,它使主线程在退出之前等待“所有线程已经结束”条件为真。最后一个线程可以通过条件变量发信号给等待中的主线程,通知它所有线程已经结束、而它是最后一个。随后主线程继续执行,退出应用并销毁进程。
ACE_Thread_Mutex mutex;
ACE_Condition<ACE_Thread_Mutex> cond(mutex);
主线程:
mutex.acquire();
while(number!=n_threads)
cond.wait(); // 阻塞在该条件变量上
mutex.release();
其他线程:arg->cond_->signal(); //满足条件,发送信号
线程常常需要特定条件被满足才能继续它的操作。例如,设想线程需要在全局消息队列里插入消息。在插入任何消息之前,它必须检查在消息队列里是否有空闲空间。如果消息队列在“满”状态,它就什么也不能做,而必须进行休眠,过一会再重试。就是说,在访问全局资源之前,某个条件必须为真。然后,当另外的线程空出消息队列时,应该有方法通知或发信号给原来的线程:在消息队列里有位置了,现在应该再次尝试插入消息。这可以使用条件变量来完成。条件变量不是被用作互斥原语,而是用作特定条件已经满足的指示器。
在使用条件变量时,你的程序应该完成以下步骤:
获取全局资源(例如,消息队列)的锁(互斥体)。
检查条件(例如,消息队列里有空间吗?)。
如果条件失败,调用条件变量的wait()方法。等待在未来条件变为真。
当另一线程在全局资源上执行操作时,它发信号(signal())给所有其他在此资源上测试条件的线程(例如,另一线程从消息队列中取出一个消息,然后通过条件变量发送信号,以使阻塞在wait()上的线程能够再尝试将它们的消息插入队列)。
在醒来之后,重新检查条件现在是否为真。如为真,则在全局资源上执行操作(例如,将消息插入全局消息队列)
需要特别注意的是,[b]在阻塞在wait调用中之前,条件变量机制(也就是ACE_Cond)负责释放全局资源上的互斥体。如果没有进行此操作,将没有其他的线程能够在此资源上工作(该资源是条件改变的原因)。同样,一旦阻塞线程收到信号、重又醒来,它在检查条件之前会在内部重新获取锁。[/b]
用ACE_Thread::join()调用可以使主线程等待其他的线程结束。另一种达到同样目的的方法是使用条件变量,它使主线程在退出之前等待“所有线程已经结束”条件为真。最后一个线程可以通过条件变量发信号给等待中的主线程,通知它所有线程已经结束、而它是最后一个。随后主线程继续执行,退出应用并销毁进程。
ACE_Thread_Mutex mutex;
ACE_Condition<ACE_Thread_Mutex> cond(mutex);
主线程:
mutex.acquire();
while(number!=n_threads)
cond.wait(); // 阻塞在该条件变量上
mutex.release();
其他线程:arg->cond_->signal(); //满足条件,发送信号