BOOST 庫 thread類線程使用 多線程處理的理解

hread庫爲C++增加了線程處理能力,它提供簡明清晰的線程、互斥量等概念,可以容易地創建多線程應用程序。thread庫也是高度可移植的,它支持使用最廣泛的windowsPOSIX[Unix下應用程序共同遵循的一種規範 ]線程,用它編寫的代碼不需要修改就可以在windowsunix等操作系統之上編譯運行。

 

使用thread[ vs2010 ]

 

1.包含thread頭文件及使用boost命名空間

#include<boost/thread.hpp>

using namespace boost;

 

2.因爲thread庫使用了date_time,所以使用時需要包含以下兩個宏

#define BOOST_DATE_TIME_SOURCE

#define BOOST_THREAD_NO_LIB

 

3.創建線程對象

thread類是thread庫的核心類,負責啓動和管理線程對象。依據類的對象被創建時首先運行構造函數的思想。

創建線程對象的形式[調用不同的構造函數就導致形式不同]爲:

thread my_thread_1( function );

thread my_thread_2( function,arg1,…,arg9 )

 

有三個構造函數,表明在創建對象時有三種不同的形式[傳遞給構造函數的參數不同 ]

1thread();

2template<class F> explicit thread(F f);

3template<class F, class A1, class A2…,class A9> thread(F f, A1 a1, A2 a2, …,A9 a9);

第(1)個構造函數不可被傳遞參數,【表示構造一個表示當前執行線程的線程對象】,第(2)、(3)兩個構造函數的區別在於使用第三個構造函數可以指定傳入調用函數的參數,最多可以傳遞9個參數。

此構造函數採用C++中模板的思想使得thread創建線程時可以對其構造函數傳入任意類型的函數及參數。

 

4.使用等待當前線程的成員函數

join()一直阻塞等待,直到當前線程結束。

time_join()等待當前線程結束或者最多等待多少時間後返回[噹噹前線程已經結束但等待時間還未到時也返回]

 注意:如果想實現多個線程交替執行就不要在子線程後加thrd.join();直接想下面寫

   boost::thread thrd1(&readSerial);  //子線程1
   boost::thread thrd2(&readQueue);  //子線程2

5.創建線程簡單例子

新建控制檯程序[配置VS2010工程環境:VS2010 boost庫環境設置]

然後植入以下代碼[ 不必在意代碼實現細節 自己編碼練習出來 ]:

[cpp] view plain copy
  1. #include "stdafx.h"  
  2.   
  3. #include <iostream>  
  4. #include <boost/thread.hpp>  
  5.   
  6. using namespace std;  
  7. using namespace boost;  
  8.   
  9. #define BOOST_DATE_TIME_SOURCE  
  10. #define BOOST_THREAD_NO_LIB  
  11.   
  12.   
  13. //----------------------------------  
  14. //函數聲明  
  15. //----------------------------------  
  16. void print_string( const string &str );  
  17.   
  18.   
  19. int _tmain(int argc, _TCHAR* argv[])  
  20. {  
  21.           
  22.         thread my_thread_1( print_string, "hello" );  
  23.     my_thread_1.join();  
  24.   
  25.     thread my_thread_2( print_string, "\nworld" );  
  26.     my_thread_2.join();  
  27.       
  28.     getchar();  
  29.     return 0;  
  30. }  
  31.   
  32.   
  33. //------------------  
  34. //打印字符串到標準流  
  35. //------------------  
  36. void print_string( const string &str )  
  37. {  
  38.         int i;  
  39.   
  40.         for( i = 0; i < str.length(); ++i ){  
  41.         cout << str[i];  
  42.     }  
  43.           
  44. }  

 

1】運行程序得到兩個線程運行的結果:窗口中無論如何都是輸出

hello

world

2】不加兩個線程對象的等待線程結束代碼即去掉*_join()代碼,則多次運行程序得到的結果爲:

有時候是hello輸出在前,有時候是world輸出在前,有時候是hello或者world字符串的輸出不連續,是helloworld隨機排列的字符串。

其實這體現了線程的執行實質:從某種角度來說,線程就是在進程的另一個空間裏運行的一個函數。現在本進程裏面創建了兩個線程,當每個線程對象被創建[主程序也相當於一個線程了 ]以後就開始執行此線程,從此多個線程交替被CPU拿去執行。根據CPU在每個時刻只能執行一個任務的特點,最後有3個線程交替運行,運行情況有多種:

(1)在程序運行時,在創建第二個線程my_thread_2之前就已經將第一個線程運行完畢,然後就將第二個線程my_thread_2的創建及運行完成,這個時候“hello”就出現在“world”的前面。

(2)在程序運行時,可能創建完第一個線程對象my_thread_1之後CPU就回到創建線程中的線程中[ main函數程序 ]來運行,一下子就完成了線程2 my_thread_2的創建及運行,然後CPU再繼續運行線程對象1my_thread_1,這就使“world”出現在“hello”之前。

(3)當程序運行時,就有可能出現將my_thread_1線程創建完畢,執行一小會兒被打斷去創建my_thread_2對象[ main函數程序 ]my_thread_2被執行一小會兒後CPU又去執行my_thread_1[此時創建線程的線程裏木有了代碼,但這個進程尚未完畢 ],如此以此種循環的方式將兩個線程間接交替的執行完畢。這樣子,輸出的hello world就有可能是隨機排列的了。

這充分體現了線程在時間上的同級性,跟代碼出現的先後在宏觀上無關[尤其是線程對象創建後,就基本上被CPU平等的執行着[設定了優先級除外 ] ]。這就是線程,一個時間段[微觀內的小時間段 ]內可以執行多個函數。給人一種可以同時執行程序中多個不同任務的感覺。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章