Boost::Thread 多線程的基礎知識


Boost.Thread可以使用多線程執行可移植C++代碼中的共享數據。它提供了一些類和函數來管理線程本身,還有其它一些為了實現在線程之間同步數據或者提供針對特定單個線程的數據拷貝。
頭文件:
#include <boost/thread.hpp>

線程定義
boost::thread 類是負責啟動和管理線程。每個boost::thread對象代表一個單獨的執行線程,是不可拷貝的。由於它是可以被移動到,所以它們可以被保存到會改變大小的容器中,並且從函數返回。這使得線程創建的詳細信息可以被封裝到一個函數中。
boost::thread make_thread();

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


啟動線程
一個新的線程可以通過傳遞一個可被調用的類型對象來啟動,這個對象可以不需要給構造器參數就被喚醒。對象被拷貝到內存,並且在最新創建的線程上喚醒。如果對象不能被拷貝,boost::ref可以以引用的方式來傳遞給函數對象。在這種情況下,用戶的boost.thread必須確保對象的引用的生命期必須比最新創建的執行線程要長。

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::Ref,只是對可調用對象的引用。
沒有指定限制傳遞的額外參數的數量。

線程中的異常
如果傳入到boost::thread構造體的函數或者可調用的對象拋出了一個異常而且喚醒它的不是boosst::thread_interrupted類型,std::terminate()會被調用來結束這個線程。

等待
當代表一個執行線程的線程對象被破壞時,這個線程變成分離的,一旦它被分離,將會繼續執行知道喚醒由構造體提供的函數或者可調用對象執行結束,或者程序已經結束。線程也可以通過調用detach()成員函數來顯示的分離。在這種情形下,線程對象將不在表示一個當前分離的線程,而是一個非線程體。
為了等待一個線程執行完畢,必須使用join()和timed_join()成員函數。join()會阻塞調用的線程直到線程結束。如果線程剛剛執行結束,或者它已經不代表一個線程,join()會立即返回。timed_join()也是類似的,但是調用它如果在指定的時間流逝后線程仍然沒有結束它也會返回。

中斷
一個正在運行的線程可以通過調用相應的boost::thread對象的interrupt()成員函數來中斷。當被中斷的線程在下次執行一個指定的中斷點(或者如果它在同時執行一個的時候被鎖)並開啟中斷時,在被中斷的線程中就會拋出一個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::restore_interruption實例可以臨時轉換一個boost::this_thread::disable_interruption實例造成的影響,只要在有問題的地方傳遞一個boost::this_thread::disable_interruption對象。這會重新恢復中斷狀態到當boost::this_thread_diable_interruption對象被構造時,並且在次禁止中斷當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()來查詢中斷的狀態。


預定義的中斷點
以下函數當允許中斷時可能會拋出boost::thread_interrupted異常。
boost::thread::join() 
boost::thread::timed_join() 
boost::condition_variable::wait() 
boost::condition_variable::timed_wait() 
boost::condition_variable_any::wait() 
boost::condition_variable_any::timed_wait() 
boost::thread::sleep() 
boost::this_thread::sleep() 
boost::this_thread::interruption_point()

線程ID
boost::thread::id類可以用來標識一個線程。每個運行的執行線程都有一個特有的ID,可以通過對應的boost::thread的get_id()成員函數來獲得ID。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM