Guarded Suspension模式用一句话可以而总结:锁歪等干通。
解释下,他的基本流程是,锁 —— while循环 —— 若不满足条件等待在条件变量 —— 干活 —— 如果有必要调用条件变量的通知。这基本上是条件变量的唯一正确写法。如果你使用条件变量却发现不是走在这条路上,要小心一点。程序员用代码说话,上代码:
Java版本,实现一个消息队列:
====================================
import java.util.LinkedList;
public class RequestQeuee {
private final LinkedList queue = new LinkedList();
public synchronized Request getRequest() {
while(queue.size <= 0) {
try{
wait();
} catch(InterruptedException e){
//忽略
}
}
return (Request)queue.removeFirst();
}
public synchronized void putRequest(Request request) {
queue.addLast(request);
notifyAll();
}
}
====================================
C++ boost版本,也是实现消息队列,功能比较强,但锁歪等干通的流程一样
====================================
#include <boost/shared_array.hpp>
#include <boost/thread.hpp>
#include <stdexcept>
#include <queue>
class MsgQueue
{
public:
typedef boost::shared_array<char> Msg;
MsgQueue(std::size_t max_size_)
: max_size(max_size_)
, close_flag(false)
{
if (max_size < 1)
{
throw std::runtime_error("MsgQueue::MsgQueue : max_size < 1");
}
}
~MsgQueue()
{
close();
}
void push(Msg msg)
{
boost::mutex::scoped_lock lock(mtx);
while (msgs.size() >= max_size && !close_flag)
{
full_cond.wait(lock);
}
if (close_flag)
{
throw std::runtime_error("MsgQueue::push : msg queue has been shutdown.");
}
msgs.push(msg);
if(msgs.size() == 1)
{
empty_cond.notify_all();
}
}
Msg pop()
{
boost::mutex::scoped_lock lock(mtx);
while (msgs.empty() && !close_flag)
{
empty_cond.wait(lock);
}
if (close_flag)
{
throw std::runtime_error("MsgQueue::pop : msg queue has been shutdown.");
}
Msg msg = msgs.front();
msgs.pop();
if(msgs.size() == max_size - 1)
{
full_cond.notify_all();
}
return msg;
}
void close()
{
close_flag = true;
{
boost::mutex::scoped_lock lock(mtx);
full_cond.notify_all();
empty_cond.notify_all();
}
}
private:
boost::mutex mtx;
boost::condition_variable_any full_cond;
boost::condition_variable_any empty_cond;
std::queue<Msg> msgs;
std::size_t const max_size;
bool close_flag;
};