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

posted @ 2017-02-21 16:51  jiu~  阅读(995)  评论(0编辑  收藏  举报