您的位置:首页 > 其它

Boost::thread库的使用

2009-10-15 05:12 302 查看

Boost::thread库的使用

2009/11/26
Kagula
 
最后更新日期
2016/12/02
 
阅读对象
本文假设读者有几下Skills
[1]在C++中至少使用过一种多线程开发库,有Mutex和Lock的概念。
[2]熟悉C++开发,在开发工具中,能够编译、设置boost::thread库。
 
 

环境

[1]Visual Studio 2005/2008 with SP1
[2]boost1.39/1.40
 

概要

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

正文

线程启动

线程可以从以下四种方式启动:
第一种用struct结构的operator成员函数启动:
struct callable
{
  
void operator()() { 
这里略去若干行代码  
}
};
 
这里略去若干行代码
 
Callable x;
Boost::thread t(x);
 
第二种以非成员函数形式启动线程
 void 
func(int nP)
 { 
这里略去若干行代码
}
这里略去若干行代码
Boost::thread
 t(func,123);
 
第三种以成员函数形式启动线程
#include <boost/bind.hpp>
 
这里略去若干行代码
 
class testBind{
public:
 
void testFunc(int
i)

{
 
cout<<”i=”<<i<<endl;

}
};
 
这里略去若干行代码
 
testBind tb;
boost::thread t(boost::bind(&testBind::testFunc,&tb,100));
 
第四种以Lambda表达方式启动
boost::thread t([](int nVal)
{
cout << nVal << " from thread" << endl;
},1000);

t.join();


 

Interruption机制

可以通过thread对象的interrupt函数,通知线程,需要interrupt。线程运行到interruption
point就可以退出。
Interruption机制举例:
#include
"stdafx.h"
#include
<iostream>
#include
<boost/thread.hpp>
using
namespace std;
 
void f()
{
    
for(int i=1;i<0x0fffffff;i++)
    
{
        
if(i%0xffffff==0)
        
{
             
cout<<"i="<<((i&0x0f000000)>>24)<<endl;
             
cout<<"boost::this_thread::interruption_requested()="<<boost::this_thread::interruption_requested()<<endl;
             
if(((i&0x0f000000)>>24)==5)
             
{
                  
boost::this_thread::interruption_point();
             
}
        
}
    
}
}
 
int _tmain(int
argc, _TCHAR* argv[])
{
    
boost::thread t(f);
    
t.interrupt();
    
t.join();  //等待线程结束
    
return 0;
}
 
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的时候,不会结束,可以参考下面的例子:
#include
"stdafx.h"
#include
<iostream>
#include
<boost/thread.hpp>
using
namespace std;
 
void f()
{
    
for(int i=1;i<0x0fffffff;i++)
    
{
        
if(i%0xffffff==0)
        
{
             
cout<<"i="<<((i&0x0f000000)>>24)<<endl;
 
             
cout<<"boost::this_thread::interruption_requested()"<<boost::this_thread::interruption_requested()<<endl;
 
             
if(((i&0x0f000000)>>24)==5)
             
{
                  
boost::this_thread::disable_interruption di;
                  
{
                      
boost::this_thread::interruption_point();
                  
}
             
}
        
}
    
}
}
 
int _tmain(int
argc, _TCHAR* argv[])
{
    
boost::thread t(f);
    
t.interrupt();
    
t.join();  //等待线程结束
 
    
return 0;
}
 
 
注意boost::this_thread::disable_interruption这条语句的使用,它可以使大括号内的interruption point不会中断当前线程。

线程同步

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

static boost::mutex g_m;
这里略去若干行代码
g_m.lock();
需要锁定的代码
g_m.unlock();
这里略去若干行代码

if(g_m.try_lock())

{
需要锁定的代码
}
这里略去若干行代码
 
 
使用lock guard的例子
#include
<iostream>
#include
<string>
#include
<boost/thread.hpp>
#include
<boost/thread/mutex.hpp>
#include
<boost/thread/locks.hpp>
 
using
namespace std;
 
static boost::mutex g_m;
 
void f(string strName)
{
    
for(int i=1;i<0x0fffffff;i++)
    
{
        
if(i%0xffffff==0)
        
{
             
boost::lock_guard<boost::mutex> lock(g_m);
             
cout<<"Name="<<strName<<" i="<<((i&0x0f000000)>>24)<<endl;
        
}
    
}
}
 
int _tmain(int
argc, _TCHAR* argv[])
{
    
boost::thread t(f,string("inuyasha"));
    
boost::thread t2(f,string("kagula"));
    
boost::thread t3(f,string("kikyou"));
 
    
{
        
boost::lock_guard<boost::mutex> lock(g_m);
        
cout<<"thread id="<<t.get_id()<<endl;
    
}
 
    
t.join();
    
t2.join();
    
t3.join();
 
    
return 0;
}
 
 
使用unique lock的例子
#include
<iostream>
#include
<string>
#include
<boost/thread.hpp>
#include
<boost/thread/mutex.hpp>
#include
<boost/thread/locks.hpp>
 
using
namespace std;
 
static boost::mutex g_m;
 
void f(string strName)
{
    
cout<<"Thread name is "<<strName<<"-----------------begin"<<endl;
    
for(int i=1;i<0x0fffffff;i++)
    
{
        
if(i%0xffffff==0)
        
{
             
boost::unique_lock<boost::mutex> lock(g_m);
 
             
cout<<"Name="<<strName<<" i="<<((i&0x0f000000)>>24)<<endl;
             

             
lock.unlock();
        
}
    
}
    
cout<<"Thread name is "<<strName<<"-----------------end"<<endl;
}
 
int _tmain(int
argc, _TCHAR* argv[])
{
    
boost::thread t(f,string("inuyasha"));
    
boost::thread t2(f,string("kagula"));
    
boost::thread t3(f,string("kikyou"));
 
    
t.join();
    
t2.join();
    
t3.join();
 
    
return 0;
}

同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函数在上面的例子已经定义
int _tmain(int
argc, _TCHAR* argv[])
{
    
boost::thread_group tg;
    
tg.add_thread(new boost::thread(f,string("inuyasha")));
    
tg.add_thread(new boost::thread(f,string("kagula")));
    
tg.add_thread(new boost::thread(f,string("kikyou")));
 
    
tg.join_all();
 
    
return 0;
}
 
 
参考来源
[1]www.boost.org
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息