1、首先考虑,什么情况下使用多线程?
第一种情况:做事情A的过程中,顺便去做事情B,不需要B完成,可以接着做A余下的部分。这种情况下,对于事情B启动一个线程,往往需要传入一个回调方法,等事情B完成后,在主线程上执行回调方法。
第二种情况:事情A和事情B同时做,他们访问同一块数据,需要对这块数据加锁。
2、考虑下面的需求,两个线程t1,t2,修改同一个数据,t1每次增加1,t2每次减2,怎么做?
a、首先肯定要准备两个方法Add1和Sub2,分别传给t1,t2;
b、准备共享资源和互斥体mutex(也就是值为1 的信号量);
c、Add1和Sub2方法内分别加锁,在加锁的语句块内,修改共享资源。
3、上面的需求,只要求一个一个访问,并没有要求t1和t2之间进行一定的协作。考虑下面的需求,t1,t2轮流打印,t1打印1,t2打印2,t1打印3,t2打印4,。。。。该怎么办?
a、当然第一步,还是必须要准备两个方法,PrintOdd和PrintEven;
b、准备共享资源和互斥体mutex;
c、Add1和Sub2方法内分别加锁,在加锁的语句块内,修改共享资源。
特别注意的是:这种情况下,加锁成功后,修改共享资源之前,必须检查修改的前提条件是否满足。也就是说,按道理轮到自己了,但是还必须要检查前提条件是否满足,如果不满足,这次把锁释放,继续下一次申请加锁。
那么,这里就有问题了。加锁成功后,前提条件不满足,不能修改,并且要释放锁。有没有更好的办法呢?
先看前提条件是否满足,不满足,不去申请加锁,因为就算加锁成功,也不能修改,没意义。
如果前提条件满足的话,才去申请加锁。特别注意的是:在加锁的语句中,需要再次检查前提条件,为什么?考虑这种极端情况,条件满足,去申请加锁,在申请加锁,到加锁成功这段时间内,假如其他线程修改了共享资源,可能导致前提条件又不满足了。因此,这里必须再次检查前提条件。
1 #include2 #include 3 #include 4 #include 5 6 using namespace std; 7 8 int num = 0; 9 boost::mutex me; 10 void Add1() 11 { 12 int i=0; 13 while(i<10) 14 { 15 me.lock(); 16 { 17 num = num+1; 18 cout<<"Add1:"< <