linux下的執行緒安全
原文結構有點亂
原理:保證同一時間只有乙個執行流對臨界資源進行訪問。
即:對臨界資源進行標記,無訪問時標記為1,有訪問時標記為0,當標記為1時,則使用者可訪問或執行緒可訪問;當標記為0時,執行緒不可訪問。
先進行判斷,能訪問則訪問,不能訪問則休眠。
mutex:是乙個計數器。
互斥鎖的**操作流程:
定義互斥鎖變數:pthread_metux_t mutex;
初始化互斥鎖:
int pthread_mutex_init(pthread_mutex_t* mutex,pthread_mutexattr_t* attr);
mutex :互斥索變數首位址;
attr : 互斥鎖屬性,通常置為null。
對臨界資源訪問時先加鎖:
兩種方式:
阻塞加鎖:int pthread_mutex_lock(pthread_mutex_t* mutex);
非阻塞加鎖:int pthread_mutex_trylock(pthread_mutex_t* mutex);
訪問結束,記得解鎖:
int pthread_mutex_unlock(pthread_mutex_t* mutex);
不用鎖了,釋放資源,銷毀互斥鎖:
int pthread_mutex_destory(pthread_mutex_t* mutex);
注意事項:
(1) 加鎖保護區域最好只是對臨界資源進行加鎖,因為保護的越多,執行所需要的時間越長,降低效率。
(2)加鎖之後在任意有可能退出執行緒的地方都要進行解鎖操作,若沒有解鎖直接退出,會造成其他執行緒訪問鎖時的狀態。
2. 死鎖:多個執行流對臨界資源爭搶訪問時,因推進順序不當,多條執行流相互等待,最終程式無法繼續執行。
當乙個執行緒互斥地訪問某個變數時,它可能發現在其它執行緒改變狀態之前,它什麼也做不了。
例如乙個執行緒訪問佇列時,發現隊列為空,它只能等待,**直到(直到後面跟著的就是條件變數)**其它執行緒將乙個節點新增到佇列中。這種情況就需要用到條件變數。
實現同步的思路是向使用者提供兩個介面(乙個是讓程序陷入阻塞等待的介面,乙個是喚醒休眠的介面)+pcb等待佇列。
條件變數的介面實現:
定義條件變數:pthread_cond_t cond;
初始化條件變數:int pthread_cond_init(pthread_cond_t* cond,pthread_condattr_t* attr);
在不滿足資源訪問時:int pthread_cond_wait(pthread_cond_t* cond,pthread_mutex_t* mutex);
//cond :條件變數 mutex: 互斥量
執行緒促使資源訪問條件滿足之後:
int pthread_cond_broadcast(pthread_cond_t *cond);//喚醒全部
int pthread_cond_signal(pthread_cond_t *cond);//喚醒乙個
銷毀:int pthread_cond_destory(pthread_cond_t* cond);
操作流程:
(1)加鎖;
(2)使用者自己進行條件判斷,不能訪問則呼叫pthread_cond_wait()陷入等待。
(3)別喚醒之後,能夠訪問,則訪問資料,獲取資源。
(4)喚醒生產資源的執行緒。
(5)加鎖。
注意事項:
(1) pthread_cond_wait() 實現了三步操作:先解鎖,陷入休眠,被喚醒後再加鎖。
(2)使用者自己進行的判斷需要用到while迴圈判斷。
(3)不同的角色應該等待在不同的條件變數上。
強調:不能與訊號概念混淆。
作用:實現執行緒間的同步與互斥。
本質:乙個計數器+pcb等待序列。
同步與互斥:
(1)實現同步:計數器對資源數量進行計數,當執行緒想要獲取資源的時候,先訪問訊號量,判斷是否能夠獲取資源(通過計數器本身),若計數器<=0,則直接堵塞執行緒,計數器-1;當其他執行緒生產資源的時候,計數器+1,喚醒等待佇列上的pcb。
(2)實現互斥:保證計數器不大於1,就表示每次最多只有乙個執行緒能夠訪問資源。
定義訊號量sem_ t sem;
初始化訊號量int sem_ init(sem_ t *sem, int pshared, int value)
在訪問臨界資源之前,先判斷計數,是否能夠訪問資源,若不能訪問,則阻塞執行緒;若可以訪問則呼叫直接返回
int sem_ wait(sem_ t *sem) / int sem trywait(sem_ t *sem)/ int sem timedwait(sem_ t *sem, struct timespec *ts)
訪問臨界資源之後/生產資源之後,喚醒乙個等待的執行緒,並且計數+ 1
int sem_ post(sem_ t *sem);
不使用訊號量記得釋放資源
int sem_ destroy(sem. _t *sem);
Linux下如何安全退出執行緒
最近發現以前工作中寫的 有個比較嚴重的bug,在這裡做一下筆記,並做適當擴充套件,防止以後出現類似的問題。有兩種方法可以設定執行緒為分離執行緒,分別是建立時設定執行緒屬性和呼叫pthread detach.下面分別來介紹這兩種方法。建立執行緒時,可以通過pthread create的第二個引數傳遞執...
Linux 執行緒安全
概念 多個執行緒同時對臨界資源進行訪問,不會造成資料二義問題 實現 同步 互斥 同步 對臨界資源訪問的時序合理性 互斥 對臨界資源同一時間訪問的唯一性 執行緒間互斥的實現 互斥鎖mutex pthread mutex t mutex 定義互斥鎖變數 pthread mutex init pthrea...
Linux 執行緒安全
多個執行緒同時訪問臨界資源,產生二義性。如何保證互斥鎖的原子訪問 互斥鎖使用過程 1.定義互斥鎖變數 pthread mutex t mutex1 2.初始化互斥鎖 int pthread mutex init pthread mutex t restrict mutex,const pthread...