您的位置:首页 > 其它

boost::condition的用法

2015-02-06 16:12 204 查看
首先我们看只有一个reader/一个writer的情形

#include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/xtime.hpp>
#include <iostream>

int number;
boost::mutex m;
boost::condition not_full;
boost::condition not_empty;

void writer()
{
while (1)
{   boost::mutex::scoped_lock sl(m);
if (number == 5) {
not_full.wait(m);
}
++number;
std::cout << "after w: " << number << std::endl;
not_empty.notify_one();
}
}

void reader()
{
while (1)
{  boost::mutex::scoped_lock sl(m);
if (number == 0) {
not_empty.wait(m);
}
--number;
std::cout << "after r: " << number << std::endl;
not_full.notify_one();
}
}

void main()
{
boost::thread trd1(&writer);
boost::thread trd2(&reader);
trd1.join();
trd2.join();
}


运行之后程序一切如常,0-5的一些数字会打印出来。

但是当另外一个write加入战局的时候,情况变得有些微妙的不同,如果我们只是在main里面加入一个writer,其他部分保持不变的话,你会看到一些错误的数字出现:

void main()
{
boost::thread trd1(&writer);
boost::thread trd11(&writer);
boost::thread trd2(&reader);
trd1.join();
trd11.join();
trd2.join();
}


究其原因是:在reader->notify_one之后并在socped_lock解锁之前,在not_full上等待的writer A被唤起,然后reader解锁,此时可能另外一个writer B先获得锁而直接增加了number。在writeB 解锁后, writerA获得锁,但此时not_full条件已经被破坏。所以一种做法是再次检查该条件,也就是这样:

while (number == 5)
{
not_full.wait(m);
}


对于多write或多reader的情形也是一样都需要以一个while循环进行conditiond的复检:完整的代码如下

#include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/xtime.hpp>
#include <iostream>

int number;
boost::mutex m;
boost::condition not_full;
boost::condition not_empty;

void writer()
{
while (1) {
boost::mutex::scoped_lock sl(m);
while (number == 5) {
not_full.wait(m);
}
++number;
std::cout << "after w: " << number << std::endl;
not_empty.notify_one();
}
}

void reader()
{
while (1) {
boost::mutex::scoped_lock sl(m);
while (number == 0) {
not_empty.wait(m);
}
--number;
std::cout << "after r: " << number << std::endl;
not_full.notify_one();
}
}

void main()
{
boost::thread trd1(&writer);
boost::thread trd11(&writer);
boost::thread trd2(&reader);
boost::thread trd22(&reader);
trd1.join();
trd11.join();
trd2.join();
trd22.join();
}


【转自:http://blog.sina.com.cn/s/blog_5d43398f0100ir1d.html】
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: