1. 程式人生 > >Boost::thread庫的使用

Boost::thread庫的使用

說明 時間 target clas quest .net variables 正文 end

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表達方式啟動

[cpp] view plain copy
  1. boost::thread t([](int nVal)
  2. {
  3. cout << nVal << " from thread" << endl;
  4. },1000);
  5. 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;

}

http://blog.csdn.net/lee353086/article/details/4673790

Boost::thread庫的使用