unix 執行緒
先來介紹執行緒的最基本操作 由淺入深
執行緒建立
pthread_t threadid; 執行緒的id儲存型別 型別為unsuigned long int
int pthread_create(pthread_t, 執行緒的唯一標識id
const pthread_attr_t *, 優先順序,排程策略,如果為null,採用預設屬性
void*(*start_rtn)(void*), 必須設定 執行緒的執行體void* (*)(void*)
void* args); 執行緒執行體的引數
成功返回 0 失敗 errno 同時設定 errno
main函式 也是乙個執行緒 如果程式沒有呼叫執行緒建立函式 那麼程式只有乙個執行緒就是main 稱為主線程 當然執行緒也分父子關係,那麼主線程就是建立所有執行緒的最高父執行緒,如果父線
程結束 ,那麼它的所有子執行緒也將結束,如果不想讓子執行緒沒有正常結束父執行緒就結束了,那麼可以通過乙個函式讓乙個執行緒等待另乙個執行緒結束,然後再向下執行
int pthread_join(pthread_t pid, //要等待的執行緒id
void **ptr) //被等待的執行緒的返回值
當然此函式是乙個堵塞函式 如果等待的執行緒一直不結束那麼,呼叫pthread_join的執行緒也將一直等待下去,然後這個函式可以讓我們的主線程不會在子執行緒退出前退出 但這個函式還有乙個作用是很重要的 乙個執行緒在預設的建立完成後它的狀態是joinable的,這個狀態的執行緒在正常結束後 如果父執行緒沒有呼叫pthread_join來等待該子執行緒那麼這個子執行緒就會變成像程序中的殭屍程序一樣(結束了但資源沒釋放),pthread_join函式不僅僅是等待它也會**這個執行緒的所占用的資源,但很多情況下我們並不希望主線程等待子執行緒的時候 堵塞在那,這時有另乙個函式出現了
pthread_detach(pthread_t )//執行緒id
可以將執行緒狀態修改為detached,這樣這個執行緒就會在正常結束後自己**資源,而且這個函式不會堵塞。
多執行緒的程式中常見的問題就是多個執行緒同時使用乙個資源 如同時去寫乙個檔案,那麼就會出現資料的混亂 也就是髒讀,可出現這種情況後要怎麼去處理呢?
建立出乙個互斥量
pthread_mutex_t t; //互斥量
pthread_mutex_init(pthread_mutex_t*, //互斥量
const pthread_mutexattr_t*)//互斥量的屬性
互斥量的使用
在我們的多執行緒程式中,找出那些不希望多個執行緒同時執行的**在**的開頭加上
pthread_mutex_lock(pthread_mutex_t*) //對互斥量的加鎖
不能多個執行緒同時執行的**...
**的結束要加上解鎖
pthread_mutex_unlock(pthread_mutex_t*)//對互斥量的解鎖
使用完畢後進行互斥量的銷毀
pthread_mutex_destroy(pthread_mutex_t*)//銷毀乙個互斥量
下面pthread_mutex_lock簡寫為lock pthread_mutex_unlock簡寫為unlock
這樣在我們互斥量的lock和unlock之間的**就只會有乙個執行緒執行,每個執行緒都會先執行到lock這部分然後程式會檢查互斥量的鎖定狀態,如果是鎖定的那麼此執行緒將進入休眠,直到互斥量不為鎖定狀態才會向下執行 這樣我們就可以通過互斥量來保證程式不會出現資源搶占的問題 可這樣那每個執行緒就都有個責任就是當乙個執行緒鎖定了資源以後,對應的就一定要對資源進行解鎖,否則其它執行緒將一直等待下去,正常狀態下是不會出現這種特殊情況的,但不知道大家有沒有考慮過如果在鎖定的**中有執行緒中斷結束的**怎麼辦,例如:return pthread_exit,一旦執行緒鎖定了資源,可是這個執行緒卻這樣沒有解鎖的退出了,怎麼辦呢??
幸好執行緒庫中也提供了這樣一對巨集函式 來解決這個問題
pthread_cleanup_push(void (*)(void*), // 指定的函式指標
void *arg); // 第1個引數的引數
pthread_cleanup_pop(int ); // 0的時候不呼叫,1的時候呼叫push
指定的函式
pthread_cleanup_push()/pthread_cleanup_pop()是以巨集方式實現的,
這是pthread.h中的巨集定義:
#define pthread_cleanup_push(routine,arg) \
可見,pthread_cleanup_push()帶有乙個"",因此這兩個函式必須成對出現 在我們使用互斥量將**鎖定以後,使用
pthread_cleanup_push(pthread_mutex_unlock,arg);
鎖定的**
pthread_cleanup_pop(0);
這樣如果在鎖定的**中出現了使執行緒結束的**,那麼在結束之前程式會呼叫push中指定的函式進行後續處理,我們可以在後續處理中對互斥量進行解鎖,這樣我們就可以避免程式進入死鎖狀態
在接收訊號的執行緒中同樣可以使用如下函式進行訊號的接收處理
sigwait(sigset_t sigs, //訊號的集合,接收到的訊號如在其中則返回
int siginfo); //接收到的訊號id
對於sigset_t集合的使用有如下幾個步驟
定義 sigset_t sigs;
sigemptyset(sigset_t*) // 對指定訊號集合初始化
sigaddset(sigset_t*,int sig) // 向訊號集合中新增訊號
sigdelset(sigset_t*,int sig) //從訊號集合中刪除訊號
sigismember(sigset_t*,int sig) //判斷訊號是否在集合中
sigfillset(sigset_t*) // 將集合中添滿所有訊號
這就是執行緒間訊號的傳送和接收處理了
個人理解 僅供參考
Unix環境多執行緒程式設計 二
資料定義標頭檔案 usr include bits pthreadtypes.h pthread attr t 執行緒屬性。屬性物件主要包括是否繫結 是否分離 堆疊位址 堆疊大小 優先順序 屬性值不能直接設定,須使用相關函式進行操作 每個屬性都有屬性名,可以單獨通過 pthread attr set...
Unix環境多執行緒程式設計 三
使用 posix 1003.1b 訊號量,有別於 systemv ipc,semctl,semop 的訊號量操作。訊號量是為執行緒間共享的資源計數。訊號量的基礎操作是 原子性的增加計數,和等待直到計數器非空並且原子性的減少計數。1 api 1.13 include 訊號量初始化 int sem in...
UNIX多執行緒資料共享與執行緒同步
在unix中,乙個程序讓另外實體進行某項事務而採取的操作為fork的乙個子程序,子進 程只是將父程序的資料區拷貝乙份到自己的資料區。在符合posix標準的unix作業系統下 同乙個程序的執行緒之間共享程序指令 大多數資料 執行緒私有資料除外 訊號處理 方式 程序執行環境等。由於執行緒共享程序的全域性...