Windows:condition_variable 两个例子
题目:子线程循环 10 次,接着主线程循环 100 次,接着又回到子线程循环 10 次,接着再回到主线程又循环 100 次,如此循环50次,试写出代码。注意:一定是子线程先执行,主线程再执行。
1 #include<iostream> 2 #include<thread> 3 #include<mutex> 4 #include<condition_variable> 5 using namespace std; 6 mutex m; 7 condition_variable cond; 8 int flag=10; 9 void fun(int num){ 10 for(int i=0;i<50;i++){ 11 unique_lock<mutex> lk(m);//A unique lock is an object that manages a mutex object with unique ownership in both states: locked and unlocked. 12 while(flag!=num) 13 cond.wait(lk);//在调用wait时会执行lk.unlock() 14 for(int j=0;j<num;j++) 15 cout<<j<<" "; 16 cout<<endl; 17 flag=(num==10)?100:10; 18 cond.notify_one();//被阻塞的线程唤醒后lk.lock()恢复在调用wait前的状态 19 } 20 } 21 int main(){ 22 thread child(fun,10); 23 fun(100); 24 child.join(); 25 return 0; 26 }
这里用的是线程的条件变量,使用条件变量与只是用线互斥程锁的不同在于:条件变量可以控制一个线程等另一个线程执行一段后再执行,或许你说这个互斥锁也可以,但确实是不同的,举例来说,你要开进程A和B,A中有一段代码需要B中的一段代码执行后再执行。如果只用了互斥锁,那你会纠结于到底是先到A那块还是先到B那块,所以互斥锁只是保证两个线程的代码不同时执行,但是要加上先后条件就需要用到条件变量了。如上题,要求是让子线程先执行,有个先后的条件,所以用条件变量更好。
题目:编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。
1 #include<iostream> 2 #include<thread> 3 #include<mutex> 4 #include<condition_variable> 5 using namespace std; 6 mutex m; 7 condition_variable cond; 8 int LOOP=10; 9 int flag=0; 10 11 void fun(int id){ 12 for(int i=0;i<LOOP;i++){ 13 unique_lock<mutex> lk(m); 14 while(id!=flag)//一定要用循环判断,若是if多个阻塞线程唤醒后同时处于临界区 15 cond.wait(lk); 16 cout<<(u_char)('A'+id)<<" "; 17 flag=(flag+1)%3; 18 cond.notify_all(); 19 } 20 } 21 int main(){ 22 thread B(fun,1); 23 thread C(fun,2); 24 fun(0); 25 cout<<endl; 26 B.join(); 27 C.join(); 28 return 0; 29 }
总结:这个题与上一个稍微复杂,因为它多了一个线程,多了一个线程问题就来了,假设有线程ABC,我们要让A先执行一部分代码,BCwait,这好办,通过条件变量让BC等待,A执行完后BC都接到信号,此时BC同时执行?不处理的话确实是同时执行,但是上题是确保B先执行,那就要注意上面代码的红色区域,通过while判断:当A执行完后,我们想执行B,那需要A执行后改变一下标志量flag,这里是加1,此时BC同时收到信号继续执行,因为while的存在,又要进行判断,这次判断的结果是B跳出while,而C继续循环停在wait处,同理,B执行后,同样设置flag,然后c跳出循环,这样就达到控制3个线程顺序的效果了。而根据需求不同,需要改变策略,但是mutex、condition_variable、flag三个全局变量配合达到控制目的是必不可少的,另外while也是实现控制的必要技巧,其它不确定技巧也基本是利用while实现。
from:http://blog.csdn.net/a809146548/article/details/51099595