Linux下的執行緒安全

2021-10-22 10:51:17 字數 2574 閱讀 8024

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...