本章介紹執行緒篇,第一篇先著重講執行緒標識,建立,終止以及一些需要注意的東西,後續繼續更新執行緒同步。
一、執行緒標識
就像每個程序擁有乙個自己的程序id一樣,每個執行緒也擁有自己的乙個執行緒id。程序id在整個系統中是唯一的,但是執行緒id不同,它只在它所屬的程序環境中有效。程序id有個資料型別pid_t來表示,他是個非負整數。執行緒id則用pthread_t資料型別來表示,但是這個資料型別在移植的時候不能
簡單的當成整數來處理,因此需要使用函式來判定兩個執行緒id是否相等;
#include
int pthread_equal(pthread_t tid1,pthread_t tid2);//若相等則返回非0值,否則返回0
執行緒需要獲取自己的id可使用pthread_self()函式獲取
#include
pthread_t pthread_self(void);
二、執行緒建立
新增執行緒的建立可以呼叫pthread_create函式建立;
#include
int pthread_create(pthread_t *tid,const pthread_attr_t *attr,void *(*start)(void),void *arg);//成功返回0,失敗返回錯誤編號
當pthread_create成功返回時,tid指向的記憶體單元被設定為新建立執行緒的執行緒id。
attr引數用於定製各種不同的執行緒屬性,可設定為null,建立執行緒時會使用預設的屬性。
新建立的執行緒從start函式的位址開始執行,該函式只有乙個無型別的指標引數arg,如果需要向start函式傳遞多個引數,需要把這些引數放到乙個結構中,然後把這個結構的位址作為arg引數傳入。
執行緒建立後並不能保證哪個執行緒先執行,可能是新建立的執行緒,也可能是呼叫執行緒。新建立的執行緒可以訪問程序的位址空間,並且繼承呼叫執行緒
的浮點環境和訊號遮蔽字,但是該執行緒的未決訊號集被清除。
例子:
#include #include pthread_t ntid;
void printids(const char* src)
void *thr_fn(*arg)
int main()
這個例子要說明兩個問題:
1、要處理主線程和新執行緒之間的競爭,所以主線程要用sleep,否則,因主線程和新執行緒誰先執行的不確定性,新執行緒可能在執行之前
主線程已經退出了。導致新執行緒無法執行。
2、新執行緒獲取自己的id要使用pthread_self()函式獲取,不能從全域性變數ntid得到,因為新執行緒可能在主線程之前執行,這樣直接
獲取的ntid是不正確的。
linux下執行緒id比較合理,但是程序id的獲取卻並不匹配,這和linux執行緒的實現有關,linux使用clone系統呼叫來實現pthread_create,
clone系統呼叫建立子程序,這個子程序可以共享父程序一定數量的執行環境,而且這個數量可配。
三、執行緒終止
程序的任意執行緒呼叫了exit,_exit,_exit,那麼整個程序就會終止。以此類似,如果訊號的預設動作是終止程序,那麼將該訊號發
送到執行緒也會終止整個程序。
單個執行緒有三種方式退出,在不終止整個程序的情況下停止它的控制流
1、執行緒指示從啟動歷程中返回,返回值是執行緒的終止碼
2、執行緒可以被統一程序中的其他執行緒終止取消
3、執行緒呼叫pthread_exit。
例子比較少,會在後續持續更新,希望繼續關注!
unix環境高階程式設計之訊號篇(一)
一 引言 訊號是軟體中斷,很比較重要的應用程式都需要處理訊號。訊號提供了一種處理非同步事件的方法,例如,中斷使用者鍵入中斷鍵,則會通過訊號機制停止乙個程式,或及早終止管道中的下乙個程式。二 概念 每乙個訊號都有乙個名字。這些名字都是以sig開頭,如sigabrt是夭折訊號,當程序呼叫abort函式時...
unix環境高階程式設計之環境搭建
首先,apue.h不是系統自有的,而是做著自己的寫的,因此,本書程式設計的第一步就是將該檔案包含下來 2.執行一下 ls,發現多了乙個apue.3e,cd 命令進入該目錄 3.執行 make 第三步一般都會出錯,提示是需要 bsd,執行 apt yum install y libbsd dev,重新...
UNIX環境高階程式設計之syslog
核心程式可以呼叫log函式記日誌.任何使用者程序可以開啟並讀取 dev klog裝置讀取這些訊息 大多數使用者程序,呼叫syslog函式產生日誌訊息.這使得訊息傳送到unix域資料報套接字 dev log 使用者程序傳送日誌訊息到udp埠514 通常syslogd守護程序會讀取乙個配置檔案 etc ...