Linux:線程同步

線程同步

同步: 在保證數據安全的前提下,讓線程能夠按照某種特定的順序訪問臨界資源,從而有效避免飢餓問題,叫做同步。
競態條件: 因爲時序問題,而導致程序異常,我們稱之爲競態條件。

沒有同步導致的飢餓問題:
假如有一個線程,它非常強勢,它一直都在申請鎖,然後申請完了釋放鎖,釋放完了又不給別的線程留機會,自己又去申請鎖,那麼此時如果有線程想要訪問臨界資源就必須等它徹底走了,那麼有越來越多的線程想要訪問臨界資源,這個線程又一直不給讓路,那麼就會導致其他線程長時間得不到CPU資源從而導致其他線程的飢餓問題。所以這種情況就應該要加上同步機制,讓這個線程申請一次釋放之後就排在等待隊列最後進行等待按順序訪問臨界資源,讓其他線程進行臨界資源的訪問。

沒有同步導致的效率問題:
假如,有一個讀線程,一個寫線程,它們往管道里進行數據的讀寫,那麼如果寫線程寫滿了,該讓讀線程來讀取數據了,但是此時讀線程不知道已經寫好了,一直不去讀,寫線程就會不斷地去檢測管道里是否有空間可以寫數據,這樣就會造成效率的低下,因此此時需要加上同步機制,當寫線程寫完的條件滿足時,通知讀線程來進行數據的讀取,同樣的,讀線程讀完的條件滿足時,通知寫線程來進行數據的寫入,這樣就達到了按照一定的順序訪問臨界資源。

所以需要引入條件變量相關函數來解決線程的等待和通知問題:

  1. 條件不滿足時,就掛起等待
  2. 條件滿足時通過條件變量就會通知另外的進程來執行其他的操作
初始化:pthread_cond_init
int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);

參數:
cond: 要初始化的條件變量
attr: 屬性,一般設置爲NULL

銷燬:pthread_cond_destroy
int pthread_cond_destroy(pthread_cond_t *cond)
等待條件滿足:pthread_cond_wait
int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);

參數:
cond: 要在這個條件變量上等待(把當前線程掛起)
mutex: 互斥量(把當前線程拿到的鎖釋放)

爲什麼第二個參數要傳互斥量?
因爲等待條件滿足是在臨界區裏等待的,如果某個線程直接進行等待,那麼就會抱着鎖去等待,此時,其他線程也無法進入臨界資源。

  • 條件等待是線程間同步的一種手段,如果只有一個線程,條件不滿足,一直等下去都不會滿足,所以必須要有一個線程通過某些操作,改變共享變量,使原先不滿足的條件變得滿足,並且友好的通知等待在條件變量上的線程。
  • 條件不會無緣無故的突然變得滿足了,必然會牽扯到共享數據的變化。所以一定要用互斥鎖來保護。沒有互斥鎖就無法安全的獲取和修改共享數據。
    在這裏插入圖片描述
喚醒等待:pthread_cond_signal/phread_cond_broadcast
int pthread_cond_broadcast(pthread_cond_t *cond);
int pthread_cond_signal(pthread_cond_t *cond);

pthread_cond_broadcast喚醒多個線程
pthread_cond_signal喚醒一個線程

條件變量使用規範

等待條件代碼

pthread_mutex_lock(&lock);     ------上鎖
while(條件不成立)
{
	pthread_cond_wait(&cond);  ------條件不成立時掛起等待(注意是while}
進行操作......                  ------修改、操作
pthread_mutex_unlock(&lock);   ------解鎖

給條件發信號代碼

pthread_mutex_lock(&lock);     ------上鎖
設置條件爲真...                 ------符合條件
pthread_cond_signal(&cond);    ------喚醒
pthread_mutex_unlock(&lock);   ------解鎖

示例代碼

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章