線程間的同步和通信


了解過了進程間的同步和通信,下面了解線程間的同步和通信。

相關知識點:進程和線程信號量機制進程同步互斥進程間通信

多線程OS通常提供多種同步機制。

 

互斥鎖(mutex)

同進程互斥類似,它實現線程間對資源的互斥訪問。

由於操作互斥鎖的時間和空間開銷都較低,因而較適合於高頻度使用的關鍵共享數據和程序段。互斥鎖有兩種狀態,即開鎖(unlock)和關鎖(lock)狀態。

當一個線程需要讀/寫共享數據段時,首先判別該共享數據段所設置的mutex 的狀態,如果它已處於關鎖狀態(不可用),則線程將被阻塞;如果 mutex 是處於開鎖狀態(可用),則將 mutex 關鎖(設置標識)后便去讀/寫該數據段。在線程完成讀/寫后,必須再發出開鎖命令將 mutex 開鎖(恢復標識),同時還須將阻塞在該互斥鎖上的一個線程喚醒,其它的線程仍被阻塞在等待 mutex 打開的隊列上。

 

線程對資源的互斥訪問 與 之前總結的臨界資源、臨界區一樣。

上述讀/寫共享數據段的過程相當於記錄型信號量,互斥鎖是資源,資源數為1。關鎖即資源數為0了。下圖是記錄型信號量的wait()和signal()描述,相當於互斥鎖的關鎖、開鎖。

記錄型信號量可能出現死鎖,一個進程要求臨界資源越多、死鎖可能性越大。信號量機制中有詳細總結。

 線程的互斥鎖,也同樣存在可能死鎖的問題。

類似的:

有兩個線程A、B。兩個臨界資源D、E,互斥鎖分別是Dmutex、Emutex。

若A、B都需要D和E,按下面情況,無外界干預線程A、B即陷入死鎖狀態。同樣需要資源越多,線程死鎖可能也越大。

thread A: 對Dmutex關鎖成功,再對Emutex關鎖失敗(需要E,但E被線程B持有),於是A阻塞,而Dmutex一直處於關鎖狀態

thread B: 對Emutex關鎖成功,再對Dmutex關鎖失敗(需要D,但D被線程A持有),於是B阻塞,而Emutex一直處於關鎖狀態


條件變量

為了解決類似上述互斥鎖中死鎖問題引入了條件變量。

每一個條件變量通常都與一個互斥鎖一起使用,亦即,在創建一個互斥鎖時便聯系着一個條件變量。

單純的互斥鎖用於短期鎖定,主要是用來保證對臨界區的互斥進入。而條件變量則用於線程的長期等待,直至所等待的資源成為可用的資源。

利用互斥鎖和條件變量訪問資源,大致描述如下:

//定義
mutex:互斥鎖
resource:資源
condition:條件變量

///申請過程
Lock mutex
if(resource busy) 
    wait(condition);
mark resource as busy;
unlock mutex;

///釋放過程
Lock mutex
mark resource as free;
unlock mutex;
wakeup(condition);

線程先對mudex關鎖,進入臨界區。若資源忙不可用,線程變轉入等待隊列(條件變量相關的隊列),然后對mudex開鎖;若資源空閑,標記資源為忙碌,再對mudex開鎖。

使用資源的線程完成釋放資源時,mudex關鎖進入,標記資源空閑,再對mudex開鎖,然后從條件變量的隊列中喚醒一個線程。喚醒的就是之前進入等待中的線程,能夠繼續執行了。

類似管程機制中的條件變量。


信號量機制

進程同步工具:信號量機制。也可用於多線程OS中,實現多線程或進程之間的同步。

1) 私用信號量(private samephore)

當某線程需利用信號量來實現同一進程中各線程之間的同步時,可調用創建信號量的命令來創建一私用信號量。

數據結構存放在應用程序的地址空間中。私用信號量屬於進程所有,OS並不知道私用信號量的存在。

2) 公用信號量(public semaphort)

公用信號量是為實現不同進程間各線程之間的同步而設置的。

由於它有着一個公開的名字供所有的進程使用,故而把它稱為公用信號量。其數據結構是存放在受 保護的系統存儲區中,由 OS 為它分配空間並進行管理,故也稱為系統信號量。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM