pthread_once

有時候我們需要對一些posix變數只進行一次初始化,如執行緒鍵。如果我們進行多次初始化程式就會出現錯誤。

在傳統的順序編程中,一次性初始化經常通過使用布爾變數來管理。控制變數被靜態初始化為0,而任何依賴於初始化的代碼都能測試該變數。如果變數值仍然為0,則它能實行初始化,然後將變數置為1。以後檢查的代碼將跳過初始化。

一次性初始化,介紹,

一次性初始化

有時候我們需要對一些posix變數只進行一次初始化,如執行緒鍵。如果我們進行多次初始化程式就會出現錯誤。
在傳統的順序編程中,一次性初始化經常通過使用布爾變數來管理。控制變數被靜態初始化為0,而任何依賴於初始化的代碼都能測試該變數。如果變數值仍然為0,則它能實行初始化,然後將變數置為1。以後檢查的代碼將跳過初始化。
但是在多執行緒程式設計中,事情就變的複雜的多。如果多個執行緒並發地執行初始化序列代碼,可能有2個執行緒發現控制變數為0,並且都實行初始化,而該過程本該僅僅執行一次。
如果我們需要對一個posix變數靜態的初始化,可使用的方法是用一個互斥量對該變數的初始化進行控制。但有時候我們需要對該變數進行動態初始化,pthread_once就會方便的多。

介紹

POSIX的只執行一次的pthread_once#ifdefWIN32#include<windows.h>#defineSLEEP(ms)Sleep(ms)#elseifdefined(LINUX)#include<stdio.h>#defineSLEEP(ms)sleep(ms)#endif#include<cassert>#include<pthread.h>//取出執行緒的IDintGetThreadID(){#ifdefWIN32return(int)pthread_getw32threadhandle_np(pthread_self());#elseifdefined(LINUX)return(int)pthread_self();#endif}//該靜態變數被所有執行緒使用staticints_nThreadResult=0;staticpthread_once_tonce=PTHREAD_ONCE_INIT;//該初始化函式,我在多執行緒下只想執行一次voidthread_init(){s_nThreadResult=-1;printf("[Child%0.4x]loopingi(%0.8x)\n",GetThreadID(),s_nThreadResult);}void*theThread(void*param){//通過once的控制,thread_init只會被執行一次pthread_once(&once,&thread_init);printf("[Child%0.4x]loopingi(%0.8x)\n",GetThreadID(),s_nThreadResult);s_nThreadResult++;pthread_exit(&s_nThreadResult);returnNULL;}intmain(intargc,char*argv[]){pthread_ttid1,tid2;pthread_create(&tid1,NULL,&theThread,NULL);pthread_create(&tid2,NULL,&theThread,NULL);//無論是否休眠,兩個子執行緒最終都會被主執行緒join到//因為兩個子執行緒都是默認的PTHREAD_CREATE_JOINABLE類型//SLEEP(3);void*status=NULL;intrc=pthread_join(tid1,&status);assert(rc==0&&"pthread_join1",rc);if(status!=PTHREAD_CANCELED&&status!=NULL){printf("Returnedvaluefromthread:%d\n",*(int*)status);}rc=pthread_join(tid2,&status);assert(rc==0&&"pthread_join2",rc);if(status!=PTHREAD_CANCELED&&status!=NULL){printf("Returnedvaluefromthread:%d\n",*(int*)status);}return0;}

相關詞條

熱門詞條

聯絡我們