今天带来boost中条件等待的线程同步的方式,先来看代码吧!
#include <boost/thread.hpp>
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
boost::mutex mutex;
boost::condition_variable_any cond;
std::vector<int> random_numbers;
void fill()
{
std::srand(static_cast<unsigned int>(std::time(0)));
for (int i= 0; i < 3; ++i)
{
boost::unique_lock<boost::mutex> lock(mutex);
random_numbers.push_back(i/*std::rand()*/);
cond.notify_all();
cond.wait(mutex);
}
}
void print()
{
std::size_t next_size = 1;
for (int i = 0; i < 3; ++i)
{
boost::unique_lock<boost::mutex> lock(mutex);
while (random_numbers.size() != next_size)
cond.wait(mutex);
std::cout << random_numbers.back() << std::endl;
++next_size;
cond.notify_all();
}
}
int main()
{
boost::thread t1(fill);
boost::thread t2(print);
t1.join();
t2.join();
system("pause");
}
然后我们来看程序的运行结果:
主要来解释下boost::condition_variable_any cond;这个东西的使用,这个是boost库中的条件变量,我们让程序的打印等到程序有新的数据到达时才进行打印输出。
fill()
函数用在每个迭代产生一个随机数,然后放在 random_numbers 容器中。 为了防止其他线程同时访问这个容器,就要相应得使用一个排它锁。 不是等待一秒,实际上这个例子却用了一个条件变量。 调用 notify_all()
会唤醒每个哪些正在分别通过调用wait()
等待此通知的线程。
通过查看 print()
函数里的 for
循环,可以看到相同的条件变量被 wait()
函数调用了。 如果这个线程被 notify_all()
唤醒,它就会试图这个互斥量,但只有在 fill()
函数完全释放之后才能成功。
这里的窍门就是调用 wait()
会释放相应的被参数传入的互斥量。 在调用 notify_all()
后, fill()
函数会通过 wait()
相应地释放线程。 然后它会阻止和等待其他的线程调用 notify_all()
,一旦随机数已写入标准输出流,这就会在 print()
里发生。
注意到在 print()
函数里调用 wait()
事实上发生在一个单独 while
循环里。 这样做的目的是为了处理在 print()
函数里第一次调用 wait()
函数之前随机数已经放到容器里。 通过比较 random_numbers 里元素的数目与预期值,发现这成功地处理了把随机数写入到标准输出流。
好了这里的技巧就说明到这里。