Unix C++(boost) 线程同步和线程组
#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(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();
}
编译后输出:
703604841---
397897602---
2011646528---
这个样例的程序删除了 wait()
和 count()
。
线程不用在每一个循环迭代中等待一秒。而是尽可能快地运行。此外。没有计算总额。数字全然写入标准输出流。
为确保正确地处理随机数,须要一个同意检查多个线程之间特定条件的条件变量来同步不每一个独立的线程。
正如上面所说。 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 里元素的数目与预期值,发现这成功地处理了把随机数写入到标准输出流。
#include<boost/thread.hpp>
#include<iostream>
using namespace std;
void f1(){
cout<<"f1()"<<endl;
}
void f2(){
cout<<"f2()"<<endl;
}
int main(){
boost::thread_group grp;
for(int i=0;i<3;++i)
{
grp.create_thread(f1);
}
grp.add_thread(new boost::thread(f2));
cout<<grp.size()<<endl;
grp.join_all();
return 1;
}
编译后输出:
4
f1()
f1()
f2()
f1()
这个程序演示了线程组的使用方法。