Linux下C的執行緒同步機制

2021-08-20 08:58:25 字數 3075 閱讀 3563

c裡提供了保證執行緒安全性的三種方法:

(新增標頭檔案#include,pthread 庫不是 linux 系統預設的庫,連線時需要使用靜態庫 libpthread.a, 在編譯中要加 -lpthread引數)

通過鎖的機制實現執行緒間的互斥,同一時刻只有乙個執行緒可以鎖定它,當乙個鎖被某個執行緒鎖定的時候,如果有另外乙個執行緒嘗試鎖定這個臨界區(互斥體),則第二個執行緒會被阻塞,或者說被置於等待狀態。只有當第乙個執行緒釋放了對臨界區的鎖定,第二個執行緒才能從阻塞狀態恢復執行。

int pthread_mutex_init(pthread_mutex_t* mutex, const thread_mutexattr_t* mutexattr);初始化乙個互斥鎖。

int pthread_mutex_lock(pthread_mutex_t* mutex);如果mutex被鎖定,當前程序處於等待狀態;否則,本程序獲得互斥鎖並進入臨界區。

int pthread_mutex_trylock(pthread_mutex_t* mutex);和lock不同的時候,嘗試獲得互斥鎖不成功不會使得程序進入阻塞狀態,而是繼續返回執行緒執行。該函式可以有效避免迴圈等待鎖,如果trylock失敗可以釋放已經占有的資源,這樣可以避免死鎖。

int pthread_mutex_unlock(pthread_mutex_t* mutex);釋放互斥鎖,並使得被阻塞的執行緒獲得互斥鎖並執行。

int pthread_mutex_destroy(pthread_mutex_t* mutex);用來撤銷互斥鎖的資源。

pthread_mutex_t mutex;

pthread_mutex_init(&mutex,null);

void pthread1(void*arg)

void pthread2(void*arg)

讀寫鎖與互斥量類似,不過讀寫鎖允許更高的並行性。適用於讀的次數大於寫的次數的資料結構。

一次只有乙個執行緒可以占有寫模式的讀寫鎖,但是多個執行緒可以同時占有讀模式的讀寫鎖。

讀鎖鎖住,加讀鎖,可以;加寫鎖會被阻塞,但此時會阻塞後續的讀鎖請求,防止讀鎖長期占用無法進入寫模式。寫鎖就是互斥鎖。

int pthread_rwlock_init(pthread_rwlock_t* rwlock, const pthread_rwlockattr_t* attr);初始化讀寫鎖

int pthread_destroy(pthread_rwlock_t* rwlock);銷毀讀寫鎖

int pthread_rwlock_rdlock(pthread_rwlock_t* rwlock);加讀鎖

int pthread_rwlock_wrlock(pthread_rwlock_t* rwlock);加寫鎖

int pthread_rwlock_unlock(pthread_rwlock_t* rwlock);解鎖

訊號量只有鎖住和不鎖兩種狀態,而且當條件變數和訊號量一起使用時,允許執行緒以無競爭的方式等待特定的條件發生。

條件本身是由互斥量保護的:執行緒在改變條件狀態之前必須先鎖住互斥量。

int pthread_cond_init(pthread_cond_t* cond,const pthread_condattr_t* attr);初始化動態分配的條件變數;也可以直接用pthread_initializer直接賦值給靜態的條件變數

int pthread_cond_destroy(pthread_cond_t* cond)撤銷條件變數資源;

int pthread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex);使用該函式使得等待條件變數為真。執行緒被條件變數cond阻塞。

int pthread_cond_timedwait(pthread_cond_t* cond, pthread_mutex_t* mutex,const struct timespec* tspr);與wait類似,只是經歷tspr時間後,即使條件變數不滿足,阻塞也被解除,返回錯誤碼。

int pthread_cond_signal(pthread_cond_t* cond);喚醒因為條件變數阻塞的執行緒。

int pthread_cond_broadcast(pthread_cond_t* cond);喚醒等待該條件的所有執行緒。

pthread_cond_t cond;

pthread_mutex_t mutex;

int count=0

;void pthread1(void*arg)

void pthread2(void*arg)

互斥量阻塞執行緒的方式是使其進入睡眠,而自旋鎖是讓執行緒忙等,即不會使其睡眠,而是不斷循判斷自旋鎖已經被解鎖。

適用於占用自旋鎖時間比較短的情況。

介紹一下posix(posix標準定義了作業系統應該為應用程式提供的介面標準,換句話說,為乙個posix相容的作業系統編寫的程式,應該可以在任何其它的posix作業系統(即使是來自另乙個廠商)上編譯執行。)的訊號量機制,定義在標頭檔案/usr/include/semaphore.h

1)初始化乙個訊號量:sem_init()

int sem_init(sem_t* sem,int pshared,unsigned int value);

pshared為0時表示該訊號量只能在當前程序的執行緒間共享,否則可以程序間共享,value給出了訊號量的初始值。

2)阻塞執行緒

sem_wait(sem_t* sem)直到訊號量sem的值大於0,解除阻塞後將sem的值減一,表明公共資源經使用後減少;sem_trywait(sem_t* sem)是wait的非阻塞版本,它直接將sem的值減一,相當於p操作。

3)增加訊號量的值,喚醒執行緒

sem_post(sem_t* sem)會使已經被阻塞的執行緒其中的乙個執行緒不再阻塞,選擇機制同樣是由執行緒的排程策略決定的。相當於v操作。

3)釋放訊號量資源

sem_destroy(sem_t* sem)用來釋放訊號量sem所占有的資源

pthread_mutex_t mutex;

sem_t full,empty;

void producer(void*arg)

}void consumer(void*arg)

}

Linux下C的執行緒同步機制

c裡提供了保證執行緒安全性的三種方法 新增標頭檔案 include,pthread 庫不是 linux 系統預設的庫,連線時需要使用靜態庫 libpthread.a,在編譯中要加 lpthread引數 通過鎖的機制實現執行緒間的互斥,同一時刻只有乙個執行緒可以鎖定它,當乙個鎖被某個執行緒鎖定的時候,...

Linux 下的同步機制

2017 03 10 回想下最初的計算機設計,在單個cpu的情況下,同一時刻只能由乙個執行緒 在linux下為程序 占用cpu,且2.6之前的linux核心並不支援核心搶占,當程序在系統位址執行時,能打斷當前操作的只有中斷,而中斷處理完成後發現之前的狀態是在核心,就不觸發地排程,只有在返回使用者空間...

執行緒同步機制

本週主要學習 執行緒同步機制 互斥量 讀寫鎖和條件變數 和簡單程式的實現,對執行緒同步有了進一步認識 內容如下 執行緒的基本概念,相關函式 互斥量 說明 處於標圓形框之上的線段表示相關的執行緒沒有擁有互斥量 處於圓形框中心線之上的線段表示相關的執行緒等待互斥量 處於圓形框中心線之下的線段表示相關的執...