執行緒同步的方法 互斥鎖 訊號量和條件變數

2021-08-05 23:40:44 字數 3282 閱讀 4137

在說執行緒的同步非同步之前,先說一下程序的同步與非同步,因為執行緒的同步與非同步基本上是乙個概念,只是將程序之間的關係修改為執行緒之間的關係 。

1、同步:當乙個程序/執行緒在執行某個請求的時候,請求的資訊需要等一段時間才能夠返回,那麼該程序/執行緒就一直等待,直到請求的資訊返回。

2、非同步:當乙個程序/執行緒在執行某個請求的時候,不必等待請求資訊的返回,直接執行接下來的操作。不管其他程序/執行緒的狀態。當有訊息返回時系統會通知程序/執行緒進行處理,這樣可以提高執行的效率。

簡單來說:同步需要等待,非同步不需要等待。

全域性變數共享-》程序內所有的執行緒都可以操作全域性變數。

例如:需要在函式執行緒中統計使用者輸入的單詞個數,在主線程中獲取使用者輸入,放入全域性字元陣列。

(1)互斥鎖

允許程式設計師鎖住某個物件,使得每次只能有乙個執行緒訪問他。為了控制關鍵**的訪問,必須在進入這段**之前鎖住乙個互斥量,然後再完成操作之後解鎖它。

用於互斥鎖的基本函式:

#include

int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutexattr_t *mutexattr);//初始化

int pthread_mutex_lock(pthread_mutex_t *mutex);//加鎖

int pthread_mutex_unlock(pthread_mutex_t *mutex);//解鎖

int pthread_mutex_destroy(pthread_mutex_t *mutex);//銷毀鎖

用互斥鎖解決上面問題:

**實現:

#include 

#include

#include

#include

#include

#include

pthread_mutex_t mutex;

char buff[128]=;

void *fun(void *arg)

}printf("count == %d\n",count);

pthread_mutex_unlock(&mutex);

sleep(1);

}}void main()

pthread_mutex_unlock(&mutex);

sleep(1);

}}

(2)訊號量

訊號量的基本函式:

#include

int sem_init(sem_t *sem,int pshared,unisigned int

value);//初始化

int sem_wait(sem_t *sem);//相當於程序中的p操作

int sem_post(sem_t *sem);//相當於程序中的v操作

int sem_destroy(sem_t *sem);//用完訊號良好對它進行清理

針對上面用互斥鎖解決的問題,用訊號量解決,**如下:

#include 

#include

#include

#include

#include

#include

#include

sem_t sem;

char buff[128]=;

void *fun(void *arg)

}printf("count == %d\n",count);

}}void main()

sem_post(&sem);

}}

(3)條件變數

在系統死鎖中有這麼乙個典型的例項:

在一條生產線上有乙個倉庫,當生產者生產的時候需要鎖住倉庫獨佔,而消費者取產品的時候也要鎖住倉庫獨佔。如果生產者發現倉庫滿了,那麼他就不能生產了,變成了阻塞狀態。但是此時由於生產者獨佔倉庫,消費者又無法進入倉庫去消耗產品,這樣就造成了乙個僵死狀態。

我們需要一種機制,當互斥量被鎖住以後發現當前執行緒還是無法完成自己的操作,那麼它應該釋放互斥量,讓其他執行緒工作。

a、可以採用輪詢的方式,不停的查詢你需要的條件

b、讓系統來幫你查詢條件,使用條件變數pthread_cond_t cond

條件變數使用之前需要初始化

a、pthread_cond_t cond = pthread_cond_initializer;

b、int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);//預設屬性為空null

條件變數使用完成之後需要銷毀

int pthread_cond_destroy(pthread_cond_t *cond);

條件變數使用需要配合互斥量

int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);

a、使用pthread_cond_wait等待條件變為真。傳遞給pthread_cond_wait的互斥量對條件進行保護,呼叫者把鎖住的互斥量傳遞給函式。

b、這個函式將執行緒放到等待條件的執行緒列表上,然後對互斥量進行解鎖,這是個原子操作。當條件滿足時這個函式返回,返回以後繼續對互斥量加鎖。

int pthread_cond_timedwait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex,const struct timespec *restrict abstime);

c、這個函式與pthread_cond_wait類似,只是多乙個timeout,如果到了指定的時間條件還不滿足,那麼就返回。時間用下面的結構體表示

struct timespec;

注意,這個時間是絕對時間。例如你要等待3分鐘,就要把當前時間加上3分鐘然後轉換到 timespec,而不是直接將3分鐘轉換到 timespec

當條件滿足的時候,需要喚醒等待條件的執行緒

int pthread_cond_broadcast(pthread_cond_t *cond);

int pthread_cond_signal(pthread_cond_t *cond);

a、pthread_cond_broadcast喚醒等待條件的所有執行緒

b、pthread_cond_signal至少喚醒等待條件的某乙個執行緒

注意,一定要在條件改變以後在喚醒執行緒

簡單來說:同步需要等待,非同步不需要等待。

執行緒互斥與同步 互斥鎖與訊號量

所謂互斥,就是不同執行緒通過競爭進入臨界區 共享的資料和硬體資源 為了防止訪問衝突,在有限的時間內只允許其中之一獨占性的使用共享資源。如不允許同時寫 同步關係則是多個執行緒彼此合作,通過一定的邏輯關係來共同完成乙個任務。一般來說,同步關係中往往包含互斥,同時對臨界區的資源會按照某種邏輯順序進行訪問。...

訊號量和互斥鎖

概念 訊號量用在多執行緒多工 同步的,乙個執行緒完成了某乙個動作就通過訊號量告訴別的執行緒,別的執行緒再進行某些動作 大家都在sem wait的時候,就阻塞在那裡 互斥鎖是用在多執行緒多工 互斥的,乙個執行緒占用了某乙個資源,那麼別的執行緒就無法訪問,直到這個執行緒unlock,其他的執行緒才開始可...

linux 執行緒互斥同步By訊號量

今天有空就研究了下linux執行緒間的同步通訊by訊號量,離校錢只是匆匆的從網上看了一點概念性的東西 其實連概念也談不上,就知道有訊號量這麼回事 對於具體的怎麼用 實現也不知道,現在正好有時間,研究了一下。sem t include int sem init sem t sem,int pshare...