標籤:聲明 aos init ror shu int target ids 設定
C++ 11中的多線程技術
C++11 新標準中引入了四個標頭檔來支援多線程編程,他們分別是 <atomic> ,<thread>,<mutex>,<condition_variable>和<future>。
<atomic>:提供原子操作功能,該頭文主要聲明了兩個類, std::atomic 和 std::atomic_flag,另外還聲明了一套 C 風格的原子類型和與 C 相容的原子操作的函數。
<thread>:執行緒模式封裝,該標頭檔主要聲明了 std::thread 類,另外 std::this_thread 命名空間也在該標頭檔中。
<mutex>:互斥量封裝,該標頭檔主要聲明了與互斥量(mutex)相關的類,包括 std::mutex 系列類,std::lock_guard, std::unique_lock, 以及其他的類型和函數。
<condition_variable>:條件變數,該標頭檔主要聲明了與條件變數相關的類,包括 std::condition_variable 和 std::condition_variable_any。
<future>:實現了對指定資料提供者提供的資料進行非同步訪問的機制。該標頭檔主要聲明了 std::promise, std::package_task 兩個 Provider 類,以及 std::future 和 std::shared_future 兩個 Future 類,另外還有一些與之相關的類型和函數,std::async() 函數就聲明在此標頭檔中。
簡單樣本:
#include <iostream>#include <thread>using namespace std;void thread_1(){ cout << "hello from thread_1" << endl;}int main(int argc, char **argv){ thread t1(thread_1); /** join()相當於調用了兩個函數:WaitForSingleObject、CloseHandle,事實上,在vc12中也是這麼實現的 */ t1.join(); return 0;}View Code注意事項
若線程調用到的函數在一個類中,則必須將該函式宣告為靜態函數函數
因為靜態成員函數屬於靜態全域區,線程可以共用這個地區,故可以各自調用
#include <iostream> #include <pthread.h> using namespace std; #define NUM_THREADS 5 class Hello { public: //多線程調用,聲明為static static void* say_hello( void* args ) { cout << "hello..." << endl; } }; int main() { pthread_t tids[NUM_THREADS]; for( int i = 0; i < NUM_THREADS; ++i ) { int ret = pthread_create( &tids[i], NULL, Hello::say_hello, NULL ); if( ret != 0 ) { cout << "pthread_create error:error_code" << ret << endl; } } pthread_exit( NULL ); } View Code
測試結果:
hello... hello... hello... hello... hello...
View Code
代碼中如果沒有pthread_join主線程會很快結束從而使整個進程結束,從而使建立的線程沒有機會開始執行就結束了。加入pthread_join後,主線程會一直等待直到等待的線程結束自己才結束,使建立的線程有機會執行。
線程建立時屬性參數的設定pthread_attr_t及join功能的使用
線程的屬性由結構體pthread_attr_t進行管理。
typedef struct{ int detachstate; //線程的分離狀態 int schedpolicy; //線程調度策略 struct sched_param schedparam; //線程的調度參數 int inheritsched; //線程的繼承性 int scope; //線程的範圍 size_t guardsize; //線程棧末尾的警戒緩衝區大小 int stackaddr_set; void * stackaddr; //線程棧的位置 size_t stacksize; // 線程棧的大小}pthread_attr_t;
樣本:
#include <iostream> #include <pthread.h> using namespace std; #define NUM_THREADS 5 void* say_hello( void* args ) { cout << "hello in thread " << *(( int * )args) << endl; int status = 10 + *(( int * )args); //線程退出時添加退出的資訊,status供主程式提取該線程的結束資訊 pthread_exit( ( void* )status ); } int main() { pthread_t tids[NUM_THREADS]; int indexes[NUM_THREADS]; pthread_attr_t attr; //線程屬性結構體,建立線程時加入的參數 pthread_attr_init( &attr ); //初始化 pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE ); //是設定你想要指定線程屬性參數,這個參數表明這個線程是可以join串連的,join功能表示主程式可以等線程結束後再去做某事,實現了主程式和線程同步功能 for( int i = 0; i < NUM_THREADS; ++i ) { indexes[i] = i; int ret = pthread_create( &tids[i], &attr, say_hello, ( void* )&( indexes[i] ) ); if( ret != 0 ) { cout << "pthread_create error:error_code=" << ret << endl; } } pthread_attr_destroy( &attr ); //釋放記憶體 void *status; for( int i = 0; i < NUM_THREADS; ++i ) { int ret = pthread_join( tids[i], &status ); //主程式join每個線程後取得每個線程的退出資訊status if( ret != 0 ) { cout << "pthread_join error:error_code=" << ret << endl; } else { cout << "pthread_join get status:" << (long)status << endl; } } } View Code
測試結果:
hello in thread hello in thread 1hello in thread 3hello in thread 40hello in thread 2pthread_join get status:10pthread_join get status:11pthread_join get status:12pthread_join get status:13pthread_join get status:14
View Code
C++11 多線程