Linux多線程編程講解之系列八__html5

來源:互聯網
上載者:User

條件變數詳解

在 上一篇文章結束時,我描述了一個比較特殊的難題:如果線程正在等待某個特定條件發生,它應該如何處理這種情況。它可以重複對互斥對象鎖定和解鎖,每次都會檢查共用資料結構,以尋找某個值。但這是在浪費時間和資源,而且這種繁忙查詢的效率非常低。解決這個問題的最佳方法是使用 pthread_cond_wait() 調用來等待特殊條件發生。

瞭解 pthread_cond_wait() 的作用非常重要 -- 它是 POSIX 線程訊號發送系統的核心,也是最難以理解的部分。

首先,讓我們考慮以下情況:線程為查看已連結清單而鎖定了互斥對象,然而該列表恰巧是空的。這一特定線程什麼也幹不了 -- 其設計意圖是從列表中除去節點,但是現在卻沒有節點。因此,它只能:

鎖定互斥對象時,線程將調用 pthread_cond_wait(&mycond,&mymutex)。pthread_cond_wait() 調用相當複雜,因此我們每次只執行它的一個操作。

pthread_cond_wait() 所做的第一件事就是同時對互斥對象解鎖(於是其它線程可以修改已連結清單),並等待條件 mycond 發生(這樣當 pthread_cond_wait() 接收到另一個線程的“訊號”時,它將蘇醒)。現在互斥對象已被解鎖,其它線程可以訪問和修改已連結清單,可能還會添加項。

此時,pthread_cond_wait() 調用還未返回。對互斥對象解鎖會立即發生,但等待條件 mycond 通常是一個阻塞操作,這意味著線程將睡眠,在它蘇醒之前不會消耗 CPU 週期。這正是我們期待發生的情況。線程將一直睡眠,直到特定條件發生,在這期間不會發生任何浪費 CPU 時間的繁忙查詢。從線程的角度來看,它只是在等待 pthread_cond_wait() 調用返回。

現在繼續說明,假設另一個線程(稱作“2 號線程”)鎖定了 mymutex 並對已連結清單添加了一項。在對互斥對象解鎖之後,2 號線程會立即調用函數 pthread_cond_broadcast(&mycond)。此操作之後,2 號線程將使所有等待 mycond 條件變數的線程立即蘇醒。這意味著第一個線程(仍處於 pthread_cond_wait() 調用中)現在將蘇醒。

現在,看一下第一個線程發生了什麼。您可能會認為在 2 號線程調用 pthread_cond_broadcast(&mymutex) 之後,1 號線程的 pthread_cond_wait() 會立即返回。不是那樣。實際上,pthread_cond_wait() 將執行最後一個操作:重新鎖定 mymutex。一旦 pthread_cond_wait() 鎖定了互斥對象,那麼它將返回並允許 1 號線程繼續執行。那時,它可以馬上檢查列表,查看它所感興趣的更改。 停止並回顧。

那個過程非常複雜,因此讓我們先來回顧一下。第一個線程首先調用:

1 pthread_mutex_lock(&mymutex);

然後,它檢查了列表。沒有找到感興趣的東西,於是它調用:

1 pthread_cond_wait(&mycond, &mymutex);

然後,pthread_cond_wait() 調用在返回前執行許多操作:

1 pthread_mutex_unlock(&mymutex);

它對 mymutex 解鎖,然後進入睡眠狀態,等待 mycond 以接收 POSIX 線程“訊號”。一旦接收到“訊號”(加引號是因為我們並不是在討論傳統的 UNIX 訊號,而是來自 pthread_cond_signal() 或 pthread_cond_broadcast() 調用的訊號),它就會蘇醒。但 pthread_cond_wait() 沒有立即返回 -- 它還要做一件事:重新鎖定 mutex:

1 pthread_mutex_lock(&mymutex);

pthread_cond_wait() 知道我們在尋找 mymutex “背後”的變化,因此它繼續操作,為我們鎖定互斥對象,然後才返回。 pthread_cond_wait() 小測驗

現在已回顧了 pthread_cond_wait() 調用,您應該瞭解了它的工作方式。應該能夠敘述 pthread_cond_wait() 依次執行的所有操作。嘗試一下。如果理解了 pthread_cond_wait(),其餘部分就相當容易,因此請重新閱讀以上部分,直到記住為止。好,讀完之後,能否告訴我在調用 pthread_cond_wait() 之 前,互斥對象必須處於什麼狀態。pthread_cond_wait() 調用返回之後,互斥對象處於什麼狀態。這兩個問題的答案都是“鎖定”。既然已經完全理解了 pthread_cond_wait() 調用,現在來繼續研究更簡單的東西 -- 初始化和真正的發送訊號和廣播進程。到那時,我們將會對包含了多線程工作隊列的 C 代碼了如指掌。 初始化和清除

條件變數是一個需要初始化的真實資料結構。以下就初始化的方法。首先,定義或分配一個條件變數,如下所示:

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.