boost thread庫,奇怪的文件沒有Tutorial的庫,但是卻仍然相當強大
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!
boost::thread庫,奇怪的文件沒有Tutorial的庫,但是卻仍然相當強大
write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie
一直以來感覺boost的庫作為開源的庫文件是非常詳細的,絕大部分庫的文件由淺入深,一般先有Overview,從Introduction到簡單的Tutorial到複雜的example,再到rationale,應有盡有,但是boost::thread是個例外,沒有任何Introduction,Tutorial的內容,上來就是class/type的member function,標頭檔案列舉,列舉完了了事,連一個example也沒有,最奇怪的 boost庫文件絕對非其莫屬,甚至《Beyond the C++ Standard Library: An Introduction to Boost》這本書中也隻字未提
但是,不要以為此庫就是boost中最默默無名的庫了,為C++新增多執行緒庫的呼聲一直比較高(雖然B.S.以前在D&E中認為其應該由第三方庫來完成這樣和操作平臺相關性比較大的內容),虧boost::thread庫還提案了好幾次,結果文件都沒有完善-_-!起碼也算是可能進入C++標準的東西,咋能這樣呢?
最新的提案資訊,可以在其文件中搜尋到,已經進入Revision 1的階段了。《Multi-threading Library for Standard C++ (Revision 1)
其實,個人認為,一個多執行緒庫可以很簡單,實現簡單的臨界區用於同步就足夠應付絕大部分情況了,相對而言,boost::thread這樣的庫還是稍微龐大了一點。類似於Python中的thread庫其實就不錯了(據《Programming Python》作者說原型來自於JAVA),通過繼承形式使用執行緒功能(template method模式),還算比較自然,其實我們公司自己內部也實現了一套與之類似的C++版的執行緒庫,使用也還算方便。但是boost::thread走的是另一條路。由於其文件中沒有Introduction和Tutorial,我純粹是摸石頭過河似的實驗,有用的不對的地方那也就靠大家指出來了。
一、 Introduction:
boost::thread不是通過繼承使用執行緒那種用了template method模式的執行緒模型,而是通過引數傳遞函式(其實不僅僅是函式,只要是Callable,Copyable(因為需要複製到執行緒的本地資料)的就行)。這種模型是好是壞,我一下也沒有結論,但是boost::thread庫的選擇總歸是有些道理的,起碼從個人感覺來說,也更符合標準庫一貫的優先使用泛型而不是繼承的傳統和作風,這樣的模型對於與boost::function,boost::bind等庫的結合使用的確也是方便了很多,
1. 題外話:
假如你對win32/linux下的多執行緒有一定的瞭解有助於理解boost::thread的使用,假如沒有win32/linux的多執行緒使用經驗,那麼起碼也需要對多執行緒程式有概念性的瞭解,起碼對於3個概念要有所瞭解,context switching,rare conditions, atomic operation,最好也還了解執行緒間同步的一些常見形式,假如對於我上面提及的概念都不瞭解,建議先補充知識,不然,即便是HelloWorld,估計也難以理解。 另外,畢竟本文僅僅是個人學習boost::thread庫過程中的一些記錄,所以不會對作業系統,執行緒等知識有透徹的講解,請見諒。
2. boost::thread的HelloWorld:
example1:
#include <windows.h>
#include <boost/thread.hpp>
#include <iostream>
using namespace std;
using namespace boost;
void HelloWorld()
{
char* pc = "Hello World!";
do
{
cout <<*pc;
}while(*pc++);
cout <<endl;
}
void NormalFunThread()
{
thread loThread1(HelloWorld);
thread loThread2(HelloWorld);
HelloWorld();
Sleep(100);
}
int main()
{
NormalFunThread();
return 0;
}
不知道如此形式的程式夠不夠的上一個thread的helloworld程式了。但是你會發現,boost::thread的確是通過建構函式的方式,(就是建構函式),老實的給我們建立了執行緒了,所以我們連一句完成的helloworld也沒有辦法正常看到,熟悉執行緒的朋友們,可以理解將會看到多麼支離破碎的輸出,在我的電腦上,一次典型的輸出如下:
HHeellloHl eoWl olWrool rdWl!od
l d
!
呵呵,其實我不一次輸出整個字串,就是為了達到這種效果-_-!這個時候需要同步,join函式就是boost::thread為我們提供的同步的一種方式,這種方式類似於利用windows API WaitForSingleObject等待執行緒結束。下面利用這種方式來實現。
example2:
#include <boost/thread.hpp>
#include <iostream>
using namespace std;
using namespace boost;
void HelloWorld()
{
char* pc = "Hello World!";
do
{
cout <<*pc;
}while(*pc++);
cout <<endl;
}
void NormalFunThread()
{
thread loThread1(HelloWorld);
loThread1.join();
thread loThread2(HelloWorld);
loThread2.join();
HelloWorld();
}
int main()
{
NormalFunThread();
return 0;
}
這樣,我們就能完成的看到3句hello world了。但是這種方式很少有意義,因為實際上我們的程式同時還是僅僅存在一個執行緒,下一個執行緒只在一個執行緒結束後才開始執行,所以,實際中使用的更多的是其他同步手段,比如,臨界區就用的非常多,但是我在boost::thread中沒有找到類似的使用方式,倒是有mutex(互斥),其實兩者對於使用是差不多的。下面看使用了mutex同步執行緒的例子:
example3:
#include <windows.h>
#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <iostream>
using namespace std;
using namespace boost;
mutex mu;
void HelloWorld()
{
mu.lock();
char* pc = "Hello World!";
do
{
cout <<*pc;
}while(*pc++);
cout <<endl;
mu.unlock();
}
void NormalFunThread()
{
thread loThread1(HelloWorld);
thread loThread2(HelloWorld);
HelloWorld();
loThread1.join();
loThread2.join();
}
int main()
{
NormalFunThread();
return 0;
}
我們還是能看到3個完好的helloworld,並且,這在實際使用中也是有意義的,因為,在主執行緒進入HelloWorld函式時,假如第一個執行緒還沒有執行完畢,那麼,可能同時有3個執行緒存在,第一個執行緒正在輸出,第二個執行緒和主執行緒在mu.lock();此句等待(也叫阻塞在此句)。其實,作為一個多執行緒的庫,自然同步方式不會就這麼一種,其他的我就不講了。
作為boost庫,有個很大的有點就是,互相之間結合的非常好。這點雖然有的時候加大了學習的難度,當你要使用一個庫的時候,你會發現一個一個順藤摸瓜,結果都學會了,比如現在,關於boost庫的學習進行了很久了,(寫了4,5篇相關的學習文章了),從boost::for_each,boost::bind,boost::lambda,boost::function,boost:: string_algo,到現在的boost::thread,其實原來僅僅是想要好好學習一下boost::asio而已。當你真的順著學下來,不僅會發現對於C++語言的理解,對STL標準庫的理解,對於泛型的理解,等等都有更深入的瞭解,我甚至在同時學習python的時候,感覺到boost庫改變了C++的很多語言特性。。。雖然是模擬出來的。呵呵,題外話說多了,其實要表達的意思僅僅是boost::thread庫也是和其他boost庫有很多緊密結合的地方,使得其使用會非常的方便。這裡一併的在一個例子中演示一下。
example4:
#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <iostream>
#include <boost/function.hpp>
#include <boost/bind.hpp><