天天看點

boost::thread用法

最近在做一個消息中間件裡面涉及到多線程程式設計,由于跨平台的原因我采用了boost線程庫。在建立線程時遇到了幾種線程建立方式現總結如下:  

  首先看看boost::thread的構造函數吧,boost::thread有兩個構造函數: 

(1)thread():構造一個表示目前執行線程的線程對象; 

(2)explicit thread(const boost::function0<void>& threadfunc): 

     boost::function0<void>可以簡單看為:一個無傳回(傳回void),無參數的函數。這裡的函數也可以是類重載operator()構成的函數;該構造函數傳入的是函數對象而并非是函數指針,這樣一個具有一般函數特性的類也能作為參數傳入,在下面有例子。 

第一種方式:最簡單方法 

#include <boost/thread/thread.hpp> 

#include <iostream> 

void hello() 

        std::cout << 

        "Hello world, I''m a thread!" 

        << std::endl; 

int main(int argc, char* argv[]) 

        boost::thread thrd(&hello); 

        thrd.join(); 

        return 0; 

第二種方式:複雜類型對象作為參數來建立線程: 

#include <boost/thread/mutex.hpp> 

boost::mutex io_mutex; 

struct count 

        count(int id) : id(id) { } 

        void operator()() 

        { 

                for (int i = 0; i < 10; ++i) 

                { 

                        boost::mutex::scoped_lock 

                        lock(io_mutex); 

                        std::cout << id << ": " 

                        << i << std::endl; 

                } 

        } 

        int id; 

}; 

        boost::thread thrd1(count(1)); 

        boost::thread thrd2(count(2)); 

        thrd1.join(); 

        thrd2.join(); 

第三種方式:在類内部建立線程; 

(1)類内部靜态方法啟動線程 

#include <boost/thread/thread.hpp>

class HelloWorld

{

public:

 static void hello()

 {

      std::cout <<

      "Hello world, I''m a thread!"

      << std::endl;

 }

 static void start()

  boost::thread thrd( hello );

  thrd.join();

int main(int argc, char* argv[])

 HelloWorld::start();

 return 0;

在這裡start()和hello()方法都必須是static方法。 

(2)如果要求start()和hello()方法不能是靜态方法則采用下面的方法建立線程: 

#include <boost/bind.hpp>

 void hello()

    std::cout <<

    "Hello world, I''m a thread!"

    << std::endl;

 void start()

  boost::function0< void> f =  boost::bind(&HelloWorld::hello,this);

  boost::thread thrd( f );

 HelloWorld hello;

 hello.start();

(3)在Singleton模式内部建立線程: 

  boost::thread thrd( boost::bind  

                   (&HelloWorld::hello,&HelloWorld::getInstance() ) ) ;

 static HelloWorld& getInstance()

  if ( !instance )

      instance = new HelloWorld;

  return *instance;

private: 

 HelloWorld(){}

 static HelloWorld* instance;

HelloWorld* HelloWorld::instance = 0; 

第四種方法:用類内部函數在類外部建立線程; 

#include <string>

 void hello(const std::string& str)

        std::cout <<str<< std::endl;

 HelloWorld obj;

 boost::thread thrd( boost::bind(&HelloWorld::hello,&obj,"Hello 

                               world, I''m a thread!" ) ) ;

 thrd.join();

如果線程需要綁定的函數有參數則需要使用boost::bind。比如想使用 boost::thread建立一個線程來執行函數:void f(int i),如果這樣寫:boost::thread thrd(f)是不對的,因為thread構造函數聲明接受的是一個沒有參數且傳回類型為void的型别,而且不提供參數i的值f也無法運作,這時就可以寫:boost::thread thrd(boost::bind(f,1))。涉及到有參函數的綁定問題基本上都是boost::thread、boost::function、boost::bind結合起來使用