Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

 概要

        boost::thread 類的職責是啟動和管理線程對象。 大多數時候每個 boost::thread 實例代表一個獨立的線程: boost::thread 實例是不可拷貝的。

        boost::thread 實例是可轉移(movable)的 , 因此它們可以被存放到支持轉移語義(move-aware)的容器中, 由函數返回。 這樣使得線程對象的創建細節可以用函數包裝起來。

boost::thread make_thread();
void f()
{
boost::thread some_thread=make_thread();
some_thread.join();
}

         [注: 在支持右值引用的編譯器上, boost::thread 提供一個適當的轉移構造函數和轉移賦值操作, 以此來符合C++0x 中的可轉移拷貝和可轉移賦值的概念。   在這些編譯器的幫助下, boost::thread 能夠用於支持轉移語義的容器。

         對於其他的編譯器, 轉移語義由一個轉移模仿層來支持, 這樣容器需要顯式檢測模仿層。 詳細資料參考 <boost/thread/detail/move.hpp> ]

啟動線程

        通過傳遞一個擁有無參數構造函數的可調用對像來啟動一個線程。 這個對象會被拷貝,然後再線程執行的時期調用。 如果對像不支持拷貝If the object must not (or cannot) be copied, 可以通過 boost::ref 傳遞一個引用,在此種狀況下,該對像必須在線程執行期間存在。

struct callable
{
void operator()();
};
boost::thread copies_are_safe()
{
callable x;
return boost::thread(x);
} // x is destroyed, but the newly-created thread has a copy, so this is OK

boost::thread oops()
{
callable x;
return boost::thread(boost::ref(x));
} // x is destroyed, but the newly-created thread still has a reference
// this leads to undefined behaviour

          如果你希望通過帶參數的函數或可調用對像來構造一個線程對象,可以通過將額外的參數傳遞給 boost::thread 構造函數的方法來實現:

void find_the_question(int the_answer);
boost::thread deep_thought_2(find_the_question,42);

          參數會被拷貝到線程內部: 如果需要使用參數引用, 請參照可調用對象的引用方法。

          對於額外參數的個數沒有限制。

線程函數中的異常

         如果傳遞給 boost::thread構造函數的線程函數或可調用對像在被調用時產生一個非boost::thread_interrupted 類型的異常, std::terminate()會被調用

鄰連和分離

         當代表的線程執行體的 boost::thread 對像被銷毀的時候,線程執行體處於被分離的狀態(detached)。 線程執行體此時繼續執行,直到線程函數或可調用對像執行結束, 或者程序終止。 線程執行體也可以通過顯式調用boost::thread成員函數detach()分離(detach), 在這種狀況下,boost::thread 對像結束了和線程執行體的關係,不在代表任何線程執行體(Not-a-Thread)

         如果要等待一個線程結束, 使用 boost::thread 線程對象的成員函數join()timed_join()函數join() 會阻塞調用線程直到等待的線程對像執行結束。 如果等待的線程對像已經結束,或者等待的線程對像沒有關聯任何線程執行體(Not-a-Thread), 函數 join() 會立即返回。 函數timed_join()join() 類似, 只是在等待指定的時間後也會返回。

 中斷

         一個執行著的線程可以通過調用對應boost::thread 對象的函數interrupt()來中斷。 當一個被中斷的線程在中斷打開時再次執行到某個特定的中斷點  interruption points (or if it is currently blocked whilst executing one) , 它會觸發一個boost::thread_interrupted 異常。 如果這個異常沒有被捕捉,會導致該線程終止。 如同其它異常一樣, 棧會被展開, 自動變量會被析構。

        如果一個線程不希望被中斷, 可以創建一個boost::this_thread::disable_interruption對像來達到這個目的。 該對像創建成功後,線程中斷關閉,直到該對像被銷毀:

void f()
{
// interruption enabled here
{
boost::this_thread::disable_interruption di;
// interruption disabled
{
boost::this_thread::disable_interruption di2;
// interruption still disabled
} // di2 destroyed, interruption state restored
// interruption still disabled
} // di destroyed, interruption state restored
// interruption now enabled
}

          boost::this_thread::disable_interruption對像關閉的線程中斷可以通過構建一個boost::this_thread::restore_interruption對像來臨時打開, 並在構造時傳遞對應的 boost::this_thread::disable_interruption object對像 。這樣將恢復線程中斷狀態到構建  boost::this_thread::disable_interruption object對像之前 , 當boost::this_thread::restore_interruption 對像銷毀的時候,線程中斷會再次處於關閉。

void g()
{
// interruption enabled here
{
boost::this_thread::disable_interruption di;
// interruption disabled
{
boost::this_thread::restore_interruption ri(di);
// interruption now enabled
} // ri destroyed, interruption disable again
} // di destroyed, interruption state restored
// interruption now enabled
}

        在任何時候,線程中斷狀態可以通過函數 boost::this_thread::interruption_enabled()來取得 

 預定義的中斷點

        下列函數是中斷點interruption points), 會在被調用線程對像中斷開啟的情況下拋出boost::thread_interrupted 異常:

 線程標識(IDs)

         boost::thread::id 對象可用於標識線程。 每個執行期的線程都有一個唯一的標識,可通過成員函數get_id()獲得  , 或者在線程內部通過函數boost::this_thread::get_id()獲得 boost::thread::id  對像支持拷貝, 並提供完整的比較操作符,可以用於關聯式容器的鍵值 。 儘管沒有指定輸出格式,線程標識(Thread IDs) 還是可以以標準操作輸出到流。

        boost::thread::id 對象可能標識線程, 也可能沒有標識線程(Not-a-Thread)。 沒有標識線程的對象(Not-a-Thread)在比較時都是相同的, 但是和標識了線程的boost::thread::id對象都不一樣。 boost::thread::id的比較操作是一致的

#include <boost/thread/thread.hpp>
class thread
{
public:
thread();
~thread();
template <class F>
explicit thread(F f);
template <class F,class A1,class A2,...>
thread(F f,A1 a1,A2 a2,...);
template <class F>
thread(detail::thread_move_t<F> f);
// move support
thread(detail::thread_move_t<thread> x);
thread& operator=(detail::thread_move_t<thread> x);
operator detail::thread_move_t<thread>();
detail::thread_move_t<thread> move();
void swap(thread& x);
class id;
id get_id() const;
bool joinable() const;
void join();
bool timed_join(const system_time& wait_until);
template<typename TimeDuration>
bool timed_join(TimeDuration const& rel_time);
void detach();
static unsigned hardware_concurrency();
typedef platform-specific-type native_handle_type;
native_handle_type native_handle();
void interrupt();
bool interruption_requested() const;
// backwards compatibility
bool operator==(const thread& other) const;
bool operator!=(const thread& other) const;
static void yield();
static void sleep(const system_time& xt);
};
void swap(thread& lhs,thread& rhs);
thread();

效果:

創建一個未標識任何線程(Not-a-Thread)的 boost::thread 對像

拋出:

template<typename Callable>
thread(Callable func);

前置條件:

Callable 支持拷貝。

效果:

對像func 被拷貝到 thread 庫管理的內部存儲區, 這份拷貝在稍後創建的線程中被調用。 如果這個調用產生一個非boost::thread_interrupted異常,並被傳遞到庫內部 , 函數std::terminate() 會被調用。

後置條件:

*this 引用創建出來的線程執行體。

拋出:

如果出錯,拋出boost::thread_resource_error異常。

template <class F,class A1,class A2,...>
thread(F f,A1 a1,A2 a2,...);

前置條件:

參數FAn 需要支持拷貝或者轉移語義。

效果:

類似 thread(boost::bind(f,a1,a2,...))。 結果是, fan 被拷貝到線程內部存儲由線程對像訪問。

後置條件:

*this 引用創建出來的線程執行體。

拋出:

如果出錯,拋出boost::thread_resource_error異常。

備註:

目前最多支持帶九個額外參數(a1a9 )的f

~thread();

效果:

如果If *this 標識一個線程執行體, 調用函數detach()。 銷毀這個thread對像

拋出:

無。

bool joinable() const;

返回值:

如果*this 標識一個線程執行體,返回true ,否則返回 false

拋出:

void join();

前置條件:

調用線程和被調用線程不是同一線程(this->get_id()!=boost::this_thread::get_id())

效果:

如果對像標識一個線程執行體, 調用者等待線程對像執行結束。

後置條件:

如果*this 標識一個線程執行體, 線程結束。 *this 不再標識任何執行體。

拋出:

如果該線程被中斷,拋出boost::thread_interrupted 異常。

備註:

join() 是預定義中斷點( interruption points)。

bool timed_join(const system_time& wait_until);
template<typename TimeDuration>
bool timed_join(TimeDuration const& rel_time);

前置條件:

調用線程和被調用線程不是同一線程(this->get_id()!=boost::this_thread::get_id())

效果:

如果對像標識一個線程執行體, 調用者等待線程對像執行結束, 或者直到等待的時間結束。如果 *this 並不標識線程執行體, 立即返回。

返回值:

如果*this 標識一個線程執行體,並且線程在等待時間結束前結束,返回true ,否則返回 false

後置條件:

如果*this 標識一個線程執行體 , 並且函數返回true, 線程執行體已經結束, *this 不再標識任何執行體。如果函數timed_join 返回false, *this 不變。

拋出:

如果該線程被中斷,拋出boost::thread_interrupted 異常。

備註:

timed_join()預定義中斷點(interruption points)

void detach();

效果:

如果*this 標識一個線程執行體, 線程對像和執行體分離,。

後置條件:

*this 不再標識任何執行體。

拋出:

thread::id get_id() const;

返回值:

如果*this 標識一個線程執行體, 返回有效線程標識( boost::thread::id。 否則返回空的線程標識(default-constructed boost::thread::id)

拋出:

void interrupt();

效果:

如果*this 標識一個線程執行體,, 線程中斷開啟時,線程在下次進入預定義中斷點時,或線程當前在阻塞狀態下,線程被中斷。

拋出:

unsigned hardware_concurrency();

返回值:

返回當前硬件系統支持的線程數量(處理器內核數量), 如果當前信息不可用,返回 0 。

拋出:

typedef platform-specific-type native_handle_type;
native_handle_type native_handle();

效果:

返回平台相關的線程實例,該實例支持平台特定的線程訪問函數。 如果該平台不支持, 函數native_handle() 和類型native_handle_type 都不存在。

拋出:

bool operator==(const thread& other) const;

返回值:

如果比較的兩個線程對像ID相同返回true(get_id()==other.get_id())

bool operator!=(const thread& other) const;

返回值:

如果比較的兩個線程對像ID不同返回 true(get_id()!=other.get_id())

void sleep(system_time const& abs_time);

效果:

將調用線程掛起指定的時間。

拋出:

如果線程中斷,拋出boost::thread_interrupted 異常。

備註s:

sleep()是一個預定義中斷點( interruption points)。

void swap(thread& other);

效果:

交換線程對像關聯的線程執行體。

後置條件:

線程對像擁有的線程標識(ID)互換。

拋出:

無。

#include <boost/thread/thread.hpp>
void swap(thread& lhs,thread& rhs);

效果:

lhs.swap(rhs)

#include <boost/thread/thread.hpp>
class thread::id
{
public:
id();
bool operator==(const id& y) const;
bool operator!=(const id& y) const;
bool operator<(const id& y) const;
bool operator>(const id& y) const;
bool operator<=(const id& y) const;
bool operator>=(const id& y) const;
template<class charT, class traits>
friend std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const id& x);
};
id();

效果:

構造一個空線程標識對像(Not-a-Thread

拋出:

bool operator==(const id& y) const;

返回值:

如果代表同一個線程執行體, 或者都不標識任何線程(Not-a-Thread),返回true,否則返回 false

拋出:

bool operator!=(const id& y) const;

返回值:

如果代表不同的線程執行體返回,true , 否則返回false

拋出:

bool operator<(const id& y) const;

返回值:

如果兩者不同,並且boost::thread::id定義的順序中*this 在y 之前,返回true, 否則返回false

拋出:

備註:

 如果一個線程標識不標識任何線程(Not-a-Thread), 那麼它小於任何一個其他的線程標識。

bool operator>(const id& y) const;

返回值:

y<*this

拋出:

bool operator<=(const id& y) const;

返回值:

!(y<*this)

拋出:

bool operator>=(const id& y) const;

返回值:

!(*this<y)

拋出:

template<class charT, class traits>
friend std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const id& x);

效果:

將線程標識寫入輸出流。

返回值:

輸出流引用

#include <boost/thread/thread.hpp>
namespace this_thread
{
thread::id get_id();
}

返回值:

返回調用線程的線程標識對象。

拋出:

如果發生錯誤,拋出boost::thread_resource_error 異常。

#include <boost/thread/thread.hpp>
namespace this_thread
{
void interruption_point();
}

效果:

檢查當前線程是否被中斷。

拋出:

如果線程中斷開並且函數boost::this_thread::interruption_requested返回為真,拋出boost::thread_interrupted異常 。

#include <boost/thread/thread.hpp>
namespace this_thread
{
bool interruption_requested();
}

返回值:

如果當前線程要求中斷,返回true,否則返回false

拋出:

無。

#include <boost/thread/thread.hpp>
namespace this_thread
{
bool interruption_enabled();
}

返回值:

 如果線程中斷開啟,返回true,否則返回 false。

拋出:

無。

#include <boost/thread/thread.hpp>
namespace this_thread
{
template<typename TimeDuration>
void sleep(TimeDuration const& rel_time);
}

效果:

將調用線程掛起指定的時間 。

拋出:

如果線程被中斷,拋出boost::thread_interrupted 異常。

備註s:

sleep()是一個雨定義中斷點(interruption points)

#include <boost/thread/thread.hpp>
namespace this_thread
{
void yield();
}

效果:

放棄當前線程當前時間片, 允許其他線程運行。

拋出:

#include <boost/thread/thread.hpp>
namespace this_thread
{
class disable_interruption
{
public:
disable_interruption();
~disable_interruption();
};
}

   boost::this_thread::disable_interruption 對像在構造時關閉當前線程中斷, 在析構後恢復線程中斷狀態。 disable_interruption對像不支持拷貝和轉移。

disable_interruption();

效果:

存貯當前線程中斷狀態並關閉當前線程中斷。

後置條件:

函數boost::this_thread::interruption_enabled()返回 false

拋出:

無。

~disable_interruption();

前置條件:

和該對像構造函數必須在同一線程內調用。

效果:

恢復該對像改變的線程中斷狀態。

後置條件:

線程中斷狀態恢復至對像構造之前。

拋出:

無。

#include <boost/thread/thread.hpp>
namespace this_thread
{
class restore_interruption
{
public:
explicit restore_interruption(disable_interruption& disabler);
~restore_interruption();
};
}

        boost::this_thread::restore_interruption 對象的構建將當前線程的中斷狀態恢復至boost::this_thread::disable_interruption對像存儲的狀態,boost::this_thread::disable_interruption。  當該對像析構時,中斷再次關閉。 restore_interruption 對像不支持拷貝和轉移。

explicit restore_interruption(disable_interruption& disabler);

前置條件:

必須和thread::disable_interruption.對像在同一個線程創建。

效果:

恢復線程中斷狀體只最近一個有效 boost::this_thread::interruption_enabled()  對像保存的狀態。

後置條件:

boost::this_thread::interruption_enabled() 函數調用返回值和 thread::disable_interruption.對像構建前一致 。

拋出:

~restore_interruption();

前置條件:

必須和該對象的構造函數在同一個線程調用。

效果:

關閉當前線程中斷。

後置條件:

當前線程boost::this_thread::interruption_enabled() 函數調用返回false

拋出:

#include <boost/thread/thread.hpp>
template<typename Callable>
void at_thread_exit(Callable func);

效果:

拷貝 func 至線程相關存儲區。 這個拷貝在線程結束時被調用(即使線程被中斷)。.

後置條件:

 func 的拷貝被保存,線程退出時調用。

拋出:

內存分配失敗拋出std::bad_alloc異常, 如果線程庫內部出錯拋出boost::thread_resource_error異常。 如果拷貝func過程出錯,拋出其它異常。

#include <boost/thread/thread.hpp>
class thread_group:
private noncopyable
{
public:
thread_group();
~thread_group();
template<typename F>
thread* create_thread(F threadfunc);
void add_thread(thread* thrd);
void remove_thread(thread* thrd);
void join_all();
void interrupt_all();
int size() const;
};

     thread_group提供一組類似線程對象的集合。 新的線程對象可以通過函數add_thread和create_thread加入到這個集合。 thread_group 對像不支持拷貝和轉移語義。

thread_group();

效果:

 創建一個線程組,不包含任何線程對象。

~thread_group();

效果:

銷毀線程組,刪除組內的所有對象。

template<typename F>
thread* create_thread(F threadfunc);

效果:

創建新的線程對像(new thread(threadfunc)),將它添加到該組。

後置條件:

屬性(this->size() )增加1, 新線程開始運行。

返回值:

新線程對象的指針。

void add_thread(thread* thrd);

前置條件:

thrd 指向的對象可以用delete來刪除。

效果:

 thrd  指向的線程對像被添加到該線程組。

後置條件:

屬性this->size() 增加計數1。

void remove_thread(thread* thrd);

效果:

 如果 thrd 指向的對象屬於該線程組, 將該對像從該組中移除(不刪除該對像)。

後置條件:

如果 thrd 指向的對象屬於該線程組, 屬性this->size() 減少計數1。 

void join_all();

效果:

等待該組內所有線程執行結束。

後置條件:

該組內所有線程結束。

備註:

由於join() 是一個預定義的中斷點(interruption points), join_all() 也是一個中斷點。

void interrupt_all();

效果:

調用該組內線程對象的 interrupt() 函數。

int size();

返回值:

該組內線程對像數目。

拋出:


PrevUpHomeNext