Boost::thread库的使用

概要

通过实例介绍boost thread的使用方式,本文主要由线程启动、Interruption机制、线程同步、等待线程退出、Thread Group几个部份组成。

正文

线程启动

线程可以从以下三种方式启动:
第一种用struct结构的operator成员函数启动:

[cpp]  view plain copy
  1. struct callable  
  2. {  
  3.    void operator()() {  这里略去若干行代码   }  
  4. };  
  5.    
  6. 这里略去若干行代码  
  7.    
  8. Callable x;  
  9. Boost::thread t(x);  


第二种以非成员函数形式启动线程
[cpp]  view plain copy
  1. void func(int nP)  
  2. { 这里略去若干行代码  
  3. }  
  4. 这里略去若干行代码  
  5. Boost::thread t(func,123);  

第三种以成员函数形式启动线程
[cpp]  view plain copy
  1. #include <boost/bind.hpp>  
  2.   
  3. 这里略去若干行代码  
  4.   
  5. class testBind{  
  6. public:  
  7. void testFunc(int i)  
  8. {  
  9. cout<<”i=”<<i<<endl;  
  10. }  
  11. };  
  12.   
  13. 这里略去若干行代码  
  14.   
  15. testBind tb;  
  16. boost::thread t(boost::bind(&testBind::testFunc,&tb,100));  

Interruption机制

可以通过thread对象的interrupt函数,通知线程,需要interrupt。线程运行到interruption point就可以退出。
Interruption机制举例:
[cpp]  view plain copy
  1. #include "stdafx.h"  
  2. #include <iostream>  
  3. #include <boost/thread.hpp>  
  4. using namespace std;  
  5.   
  6. void f()  
  7. {  
  8. for(int i=1;i<0x0fffffff;i++)  
  9. {  
  10. if(i%0xffffff==0)  
  11. {  
  12. cout<<"i="<<((i&0x0f000000)>>24)<<endl;  
  13. cout<<"boost::this_thread::interruption_requested()="<<boost::this_thread::interruption_requested()<<endl;  
  14. if(((i&0x0f000000)>>24)==5)  
  15. {  
  16. boost::this_thread::interruption_point();  
  17. }  
  18. }  
  19. }  
  20. }  
  21.   
  22. int _tmain(int argc, _TCHAR* argv[])  
  23. {  
  24. boost::thread t(f);  
  25. t.interrupt();  
  26. t.join(); //等待线程结束  
  27. return 0;  
  28. }  

t.interrupt();告诉t线程,现在需要interrupt。boost::this_thread::interruption_requested()可以得到当前线程是否有一个interrupt请求。若有interrupt请求,线程在运行至interruption点时会结束。boost::this_thread::interruption_point();就是一个interruption point。Interruption point有多种形式,较常用的有boost::this_thread::sleep(boost::posix_time::seconds(5));当没有interrupt请求时,这条语句会让当前线程sleep五秒,若有interrupt requirement线程结束。
如何使线程在运行到interruption point的时候,不会结束,可以参考下面的例子:
[cpp]  view plain copy
  1. #include "stdafx.h"  
  2. #include <iostream>  
  3. #include <boost/thread.hpp>  
  4. using namespace std;  
  5.   
  6. void f()  
  7. {  
  8.   for(int i=1;i<0x0fffffff;i++)  
  9.   {  
  10.     if(i%0xffffff==0)  
  11.     {  
  12.       cout<<"i="<<((i&0x0f000000)>>24)<<endl;  
  13.   
  14.       cout<<"boost::this_thread::interruption_requested()"<<boost::this_thread::interruption_requested()<<endl;  
  15.   
  16.       if(((i&0x0f000000)>>24)==5)  
  17.       {  
  18.         boost::this_thread::disable_interruption di;  
  19.         {  
  20.           boost::this_thread::interruption_point();  
  21.         }  
  22.       }  
  23.     }  
  24.   }  
  25. }  
  26.   
  27. int _tmain(int argc, _TCHAR* argv[])  
  28. {  
  29. boost::thread t(f);  
  30. t.interrupt();  
  31. t.join(); //等待线程结束  
  32.   
  33. return 0;  
  34. }  

注意 boost::this_thread::disable_interruption 这条语句的使用,它可以使大括号内的interruption point不会中断当前线程。

线程同步

Boost提供了多种lock导致上手需要较长时间,还是看下面线程同步的例子比较简单,相信在多数应用中足够:

直接使用boost::mutex的例子

[cpp]  view plain copy
  1. static boost::mutex g_m;  
  2. 这里略去若干行代码  
  3. g_m.lock();  
  4. 需要锁定的代码  
  5. g_m.unlock();  
  6. 这里略去若干行代码  
  7. if(g_m.try_lock())  
  8. {  
  9. 需要锁定的代码  
  10. }  
  11. 这里略去若干行代码  

使用lock guard的例子
[cpp]  view plain copy
  1. #include <iostream>  
  2. #include <string>  
  3. #include <boost/thread.hpp>  
  4. #include <boost/thread/mutex.hpp>  
  5. #include <boost/thread/locks.hpp>  
  6.   
  7. using namespace std;  
  8.   
  9. static boost::mutex g_m;  
  10.   
  11. void f(string strName)  
  12. {  
  13. for(int i=1;i<0x0fffffff;i++)  
  14. {  
  15. if(i%0xffffff==0)  
  16. {  
  17. boost::lock_guard<boost::mutex> lock(g_m);  
  18. cout<<"Name="<<strName<<" i="<<((i&0x0f000000)>>24)<<endl;  
  19. }  
  20. }  
  21. }  
  22.   
  23. int _tmain(int argc, _TCHAR* argv[])  
  24. {  
  25. boost::thread t(f,string("inuyasha"));  
  26. boost::thread t2(f,string("kagula"));  
  27. boost::thread t3(f,string("kikyou"));  
  28.   
  29. {  
  30. boost::lock_guard<boost::mutex> lock(g_m);  
  31. cout<<"thread id="<<t.get_id()<<endl;  
  32. }  
  33.   
  34. t.join();  
  35. t2.join();  
  36. t3.join();  
  37.   
  38. return 0;  
  39. }  

使用unique lock的例子
[cpp]  view plain copy
  1. #include <iostream>  
  2. #include <string>  
  3. #include <boost/thread.hpp>  
  4. #include <boost/thread/mutex.hpp>  
  5. #include <boost/thread/locks.hpp>  
  6.   
  7. using namespace std;  
  8.   
  9. static boost::mutex g_m;  
  10.   
  11. void f(string strName)  
  12. {  
  13. cout<<"Thread name is "<<strName<<"-----------------begin"<<endl;  
  14. for(int i=1;i<0x0fffffff;i++)  
  15. {  
  16. if(i%0xffffff==0)  
  17. {  
  18. boost::unique_lock<boost::mutex> lock(g_m);  
  19.   
  20. cout<<"Name="<<strName<<" i="<<((i&0x0f000000)>>24)<<endl;  
  21.   
  22. lock.unlock();  
  23. }  
  24. }  
  25. cout<<"Thread name is "<<strName<<"-----------------end"<<endl;  
  26. }  
  27.   
  28. int _tmain(int argc, _TCHAR* argv[])  
  29. {  
  30. boost::thread t(f,string("inuyasha"));  
  31. boost::thread t2(f,string("kagula"));  
  32. boost::thread t3(f,string("kikyou"));  
  33.   
  34. t.join();  
  35. t2.join();  
  36. t3.join();  
  37.   
  38. return 0;  
  39. }  

同Lock_guard相比
[1]Unique lock中有owns lock成员函数,可判断,当前有没有被lock。
[2]在构造Unique Lock时可以指定boost::defer_lock_t参数推迟锁定,直到Unique Lock实例调用Lock。或采用下面的编码方式使用:
boost::unique_lock<boost::mutex> lock(mut,boost::defer_lock);
boost::unique_lock<boost::mutex> lock2(mut2,boost::defer_lock);
boost::lock(lock,lock2);
[3]它可以和Conditoin_variable配合使用。
[4]提供了try lock功能。


如果线程之间执行顺序上有依赖关系,直接到boost官网中参考条件变量(Condition variables)的使用。官网关于Conditon Variables的说明还是容易看懂的。
注意,使用一个不恰当的同步可能消耗掉1/2以上的cpu运算能力。
Thread Group

线程组使用示例,其中f函数在上面的例子已经定义
[cpp]  view plain copy
  1. int _tmain(int argc, _TCHAR* argv[])  
  2. {  
  3. boost::thread_group tg;  
  4. tg.add_thread(new boost::thread(f,string("inuyasha")));  
  5. tg.add_thread(new boost::thread(f,string("kagula")));  
  6. tg.add_thread(new boost::thread(f,string("kikyou")));  
  7.   
  8. tg.join_all();  
  9.   
  10. return 0;  
  11. }  

【转自:http://blog.youkuaiyun.com/lee353086/article/details/4673790】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值