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

Boost::thread庫的使用(轉)

http string col cpu 如果 定義 unlock opera stat

原文轉自 http://blog.csdn.net/lee353086/article/details/4673790

本文主要由線程啟動、Interruption機制、線程同步、等待線程退出、Thread Group幾個部份組成。

1、線程啟動。線程可以從以下四種方式啟動:

(1) 用struct結構的operator成員函數啟動

struct callable  
{  
   void operator()() {  這裏略去若幹行代碼   }  
};  
   
這裏略去若幹行代碼  
   
Callable x;  
Boost::thread t(x);  

(2) 以非成員函數形式啟動線程

void func(int nP)  
{ 這裏略去若幹行代碼  
}  
這裏略去若幹行代碼  
Boost::thread t(func,123);

(3) 以成員函數形式啟動線程

#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
));

2、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不會中斷當前線程。

3、線程同步

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;  
}

Boost::thread庫的使用(轉)