C++?boost?thread庫用法詳細講解
一、說明
boost::thread的六種使用方法總結(jié),本文初步介紹線程的函數(shù)、構(gòu)造、執(zhí)行的詳細解釋。
二、boost::thread的幾個函數(shù)
函數(shù) | 功能 |
---|---|
join() | 讓主進程等待子線程執(zhí)行完畢后再繼續(xù)執(zhí)行 |
get_id() | 獲得線程的 id 號 |
detach() | 標線程就成為了守護線程,駐留后臺運行 |
bool joinable() | 是否已經(jīng)啟動,為 join() |
thread::join()是個簡單暴力的方法,主線程等待子進程期間什么都不能做,一般情形是主線程創(chuàng)建thread object后做自己的工作而不是簡單停留在join上。
thread::join()還會清理子線程相關(guān)的內(nèi)存空間,此后thread object將不再和這個子線程相關(guān)了,即thread object不再joinable了,所以join對于一個子線程來說只可以被調(diào)用一次,為了實現(xiàn)更精細的線程等待機制,可以使用條件變量等機制。
1、可會合(joinable):這種關(guān)系下,主線程需要明確執(zhí)行等待操作,在子線程結(jié)束后,主線程的等待操作執(zhí)行完畢,子線程和主線程會合,這時主線程繼續(xù)執(zhí)行等待操作之后的下一步操作。主線程必須會合可會合的子線程。在主線程的線程函數(shù)內(nèi)部調(diào)用子線程對象的wait函數(shù)實現(xiàn),即使子線程能夠在主線程之前執(zhí)行完畢,進入終止態(tài),也必須執(zhí)行會合操作,否則,系統(tǒng)永遠不會主動銷毀線程,分配給該線程的系統(tǒng)資源也永遠不會釋放。
2、相分離(detached):表示子線程無需和主線程會合,也就是相分離的,這種情況下,子線程一旦進入終止狀態(tài),這種方式常用在線程數(shù)較多的情況下,有時讓主線程逐個等待子線程結(jié)束,或者讓主線程安排每個子線程結(jié)束的等待順序,是很困難或不可能的,所以在并發(fā)子線程較多的情況下,這種方式也會經(jīng)常使用。
三、構(gòu)造
boost::thread有兩個構(gòu)造函數(shù):
(1)thread():構(gòu)造一個表示當前執(zhí)行線程的線程對象;
(2)explicit thread(const boost::function0<void>& threadfunc):
boost::function0<void>可以簡單看為:一個無返回(返回void),無參數(shù)的函數(shù)。這里的函數(shù)也可以是類重載operator()構(gòu)成的函數(shù);該構(gòu)造函數(shù)傳入的是函數(shù)對象而并非是函數(shù)指針,這樣一個具有一般函數(shù)特性的類也能作為參數(shù)傳入,在下面有例子。
#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; }
執(zhí)行結(jié)果:
第二種情況:類重載operator()構(gòu)成的函數(shù)創(chuàng)建線程
#include <boost/thread/thread.hpp> #include <boost/thread/mutex.hpp> #include <iostream> 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; }; int main(int argc, char* argv[]) { boost::thread thrd1(count(1)); boost::thread thrd2(count(2)); thrd1.join(); thrd2.join(); return 0; }
運算結(jié)果:
第三種情況:在類內(nèi)部對static函數(shù)創(chuàng)建線程
#include <boost/thread/thread.hpp> #include <iostream> 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方法。因為static方法要比main方法提前加載,所以static方法不能調(diào)用一般方法,進一步說,static方法無法調(diào)用比它晚加載的方法,切記。 調(diào)用時用HelloWorld::start(),說明start在定義類的時候就已經(jīng)ready,無需在實例化后再調(diào)用。
第四種情況:使用boost::bind函數(shù)創(chuàng)建線程
#include <boost/thread/thread.hpp> #include <boost/bind.hpp> #include <iostream> #include <boost/function.hpp> class HelloWorld { public: void hello() { std::cout << "Hello world, I''m a thread!" << std::endl; } void start() { boost::function0< void> f = boost::bind(&HelloWorld::hello, this); //或boost::function<void()> f = boost::bind(&HelloWorld::hello,this); boost::thread thrd(f); thrd.join(); } }; int main(int argc, char* argv[]) { HelloWorld hello; hello.start(); return 0; }
1)定義函數(shù)指針 boost::function0< void> f
2)該指針與HelloWorld::hello函數(shù)綁定, boost::bind(&HelloWorld::hello, this);
3)線程與函數(shù)指針綁定 boost::thread thrd(f);
4)按照常規(guī),將對象實例化后,調(diào)用類函數(shù)。
運算結(jié)果:
第五種情況:在Singleton模式內(nèi)部創(chuàng)建線程
#include <boost/thread/thread.hpp> #include <boost/bind.hpp> #include <iostream> class HelloWorld { public: void hello() { std::cout << "Hello world, I''m a thread!" << std::endl; } static void start() { boost::thread thrd( boost::bind (&HelloWorld::hello,&HelloWorld::getInstance() ) ) ; thrd.join(); } static HelloWorld& getInstance() { if ( !instance ) instance = new HelloWorld; return *instance; } private: HelloWorld(){} static HelloWorld* instance; }; HelloWorld* HelloWorld::instance = 0; int main(int argc, char* argv[]) { HelloWorld::start(); return 0; }
此例將類對象實例化放在類內(nèi)部函數(shù)中,因此無需顯式實例化,就可以調(diào)用類內(nèi)函數(shù)。值得研究消化。
第六種情況:在類外用類內(nèi)部函數(shù)創(chuàng)建線程
#include <boost/thread/thread.hpp> #include <boost/bind.hpp> #include <string> #include <iostream> class HelloWorld { public: void hello(const std::string& str) { std::cout <<str<< std::endl; } }; int main(int argc, char* argv[]) { HelloWorld obj; boost::thread thrd( boost::bind(&HelloWorld::hello,&obj,"Hello world, I''m a thread!" ) ) ; thrd.join(); return 0; }
線程如何帶參數(shù)定義?本例就是參考方法!
到此這篇關(guān)于C++ boost thread庫用法詳細講解的文章就介紹到這了,更多相關(guān)C++ boost thread內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于C++語言實現(xiàn)機動車違章處罰管理系統(tǒng)
這篇文章主要介紹了基于C++語言實現(xiàn)機動車違章處罰管理系統(tǒng)的相關(guān)資料,需要的朋友可以參考下2016-07-07C++的類型轉(zhuǎn)換(強轉(zhuǎn))你了解嗎
這篇文章主要為大家詳細介紹了C++的類型轉(zhuǎn)換,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-02-02char str[] 與 char *str的區(qū)別詳細解析
以下是對char str[]與char *str的區(qū)別進行了詳細的介紹,需要的朋友可以過來參考下2013-09-09C語言數(shù)據(jù)結(jié)構(gòu)之單鏈表與雙鏈表的增刪改查操作實現(xiàn)
這篇文章主要為大家詳細介紹了C語言數(shù)據(jù)結(jié)構(gòu)中單鏈表與雙鏈表的增刪改查操作的實現(xiàn),相信大家如果搞懂了本文內(nèi)容,應(yīng)對復(fù)雜的鏈表類的題也就能慢慢鉆研了2022-07-07cocos2d-x學(xué)習(xí)筆記之CCLayer、CCLayerColor、CCLayerGradient、CCLayerMu
這篇文章主要介紹了cocos2d-x學(xué)習(xí)筆記之CCLayer、CCLayerColor、CCLayerGradient、CCLayerMultiplex場景層介紹,需要的朋友可以參考下2014-09-09詳解應(yīng)用程序與驅(qū)動程序通信DeviceIoControl
這種通信方式,就是驅(qū)動程序和應(yīng)用程序自定義一種IO控制碼,然后調(diào)用DeviceIoControl函數(shù),IO管理器會產(chǎn)生一個MajorFunction為IRP_MJ_DEVICE_CONTROL,MinorFunction為自己定義的控制碼的IRP,系統(tǒng)就調(diào)用相應(yīng)的處理IRP_MJ_DEVICE_CONTROL的派遣函數(shù)2021-06-06