回覆列表
-
1 # 使用者61789850891
-
2 # 使用者7141197769170
訊號量與互斥鎖之間的區別:
1. 互斥量用於執行緒的互斥,訊號量用於執行緒的同步。
這是互斥量和訊號量的根本區別,也就是互斥和同步之間的區別。
互斥:是指某一資源同時只允許一個訪問者對其進行訪問,具有唯一性和排它性。但互斥無法限制訪問者對資源的訪問順序,即訪問是無序的。
同步:是指在互斥的基礎上(大多數情況),透過其它機制實現訪問者對資源的有序訪問。在大多數情況下,同步已經實現了互斥,特別是所有寫入資源的情況必定是互斥的。少數情況是指可以允許多個訪問者同時訪問資源
2. 互斥量值只能為0/1,訊號量值可以為非負整數。
也就是說,一個互斥量只能用於一個資源的互斥訪問,它不能實現多個資源的多執行緒互斥問題。訊號量可以實現多個同類資源的多執行緒互斥和同步。當訊號量為單值訊號量是,也可以完成一個資源的互斥訪問。
3. 互斥量的加鎖和解鎖必須由同一執行緒分別對應使用,訊號量可以由一個執行緒釋放,另一個執行緒得到。
訊號量就是在一個叫做互斥區的門口放一個盒子,盒子裡面裝著固定數量的小球,每個執行緒過來的時候,都從盒子裡面摸走一個小球,然後去互斥區裡面浪(?),浪開心了出來的時候,再把小球放回盒子裡。如果一個執行緒走過來一摸盒子,得,一個球都沒了,不拿球不讓進啊,那就只能站在門口等一個執行緒出來放回來一個球,再進去。這樣由於小球的數量是固定的,那麼互斥區裡面的最大執行緒數量就是固定的,不會出現一下進去太多執行緒把互斥區給擠爆了的情況。這是用訊號量做併發量限制。另外一些情況下,小球是一次性的,執行緒拿走一個進了門,就把小球扔掉了,這樣用著用著小球就沒了,不過有另外一些執行緒(一般叫做生產者)會時不時過來往盒子裡再放幾個球,這樣就可以有新的執行緒(一般叫做消費者)進去了,放一個球進一個執行緒,這是訊號量做同步功能。你截圖裡的例子就是這個情況,主執行緒是生產者,透過sem_post往盒子裡放小球(訊號量加一),而其他執行緒是消費者,透過sem_wait從盒子裡拿小球(訊號量減一),如果遇到盒子裡一個小球都沒有(訊號量為0),就會開始等待訊號量不為0,然後拿走一個小球(訊號量減一)再繼續。本質上來說訊號量就是那個盒子,以及“摸不到球就不讓進”這個機制。順便你這個例子其實有點問題,傳送訊號量也就是放小球的這個過程並不會阻塞,會繼續執行下去,那麼有可能在消費者執行緒取走work_area裡面的資料之前,下一個fgets就把這個資料覆蓋了,這是個很危險的競爭冒險的問題,非常不符合多執行緒程式的設計準則。由於是從stdin當中讀取資料,一般來說鍵盤是沒有這麼快,但要知道完全可以把輸入重定向到檔案,這時候就很容易出問題了。