1. 程式人生 > >作業系統(8)程序--同步互斥介紹;同步問題的三種解決方案:禁用硬體中斷、基於軟體、更高階抽象

作業系統(8)程序--同步互斥介紹;同步問題的三種解決方案:禁用硬體中斷、基於軟體、更高階抽象

文章目錄

1. 背景

同步互斥是作業系統協調程序之間動作和相互關係中的機制。互斥是指當一個程序在臨界區訪問共享資源時,其他程序不能進入該臨界區訪問任何共享資源。為實施互斥,程序之間就要採用同步機制。

  1. 併發程序的正確性
    ==1==
  2. 程序併發執行的好處

    共享資源


    加速:I/O操作和CPU計算可以重疊,程式可分為多個模組在多個處理器上並行執行
    模組化:將大程式分解成小程式,使系統易於複用和擴充套件。

  3. 原子性操作
    原子性操作時作業系統硬體提供的操作,它保證一些執行語句必須是原子操作。
    ==2==

2. 同步問題的一個例子

本節用一個簡單的生活問題來理解同步。(具體分析過程詳見視訊:同步問題

  1. 下圖中,如果A和B的按照圖中的順序執行的話,就會出現麵包重複購買的情況
    ==3==
    首先來分析下這個問題:
    ==4==

  2. 解決方案
    利用兩個原子操作來實現一個鎖(lock)

    Lock.Acquire():在鎖被釋放之前一直等待,然後獲得鎖,如果兩個程序都在等待同一個鎖,並且同時發現鎖被釋放了,那麼只有一個獲得鎖,另一個仍處於等待
    Lock.Release()

    :解鎖並喚醒任何等待中的程序

    ==5==

  3. 程序的互動關係
    ==6==


3. 同步問題的初步解決方案

==7==

臨界區:程序中訪問臨界資源的一段需要互斥執行的程式碼(也就是說有一個程序在訪問臨界區程式碼,另一個程序就不能訪問該程式碼)
進入區:檢查可否進入臨界區的一段程式碼,如可進入,則設定相應“正在訪問臨界區”標誌‘
退出區:清楚“正在訪問臨界區標誌”
剩餘區:程式碼的其餘部分
臨界區訪問規則
空閒則如:沒有程序在臨界區,則任何程序可以進入
忙則等待:有程序在臨界區,其他程序均不能進入臨界區
有限等待:等待進入臨界區的程序不能無限制等待
讓權等待(可選):不能進入臨界區的程序,應釋放CPU(比如轉換到阻塞狀態)

1. 方法一 禁用硬體中斷

也就是禁止硬體中斷的響應,相當於把中斷使能關掉了。
==8==
==9==

2. 方法二 基於軟體的同步辦法

該方法就是通過程序共享一些共有變數來實現執行緒的同步。該方法的特徵一是複雜(需要兩個程序間的共享資料項),二是需要忙等待,浪費CPU時間。

  1. 示例
    ==10==

  2. Peterson演算法
    ==14==

    第一種情況:另外一個程序Tj沒有申請進入,則此時flag[j]為false,Ti可以正常進入臨界區
    第二種情亂:Tj申請進入,flag[j]為true,則先寫turn語句的會進入臨界區。比如說是Ti先寫turn=j,則此時Ti 進不去(while兩個條件都滿足,會一直迴圈),然後Tj寫turn(turn=i)後,Ti就會立馬進去了,Ti執行完臨界區程式碼後,flag[i]=false,則Tj就可以進去了。

    ==16==

  3. Dekkers演算法
    ==17==
    ==18==

3. 方法三 更高階的抽象方法

硬體提供了一些同步原語,比方說中斷禁用、原子操作指令等,作業系統提供了更高階的程式設計抽象來簡化程序的同步,比方說訊號量(這兩個都是用硬體原語來構建的)


  1. 鎖是一個抽象的資料結構,它由一個二進位制變數(鎖定/解鎖)和兩個操作原語組成。它是基於原子操作指令來實現的

    Lock.Acquire():在鎖被釋放之前一直等待,然後獲得鎖,如果兩個程序都在等待同一個鎖,並且同時發現鎖被釋放了,那麼只有一個獲得鎖,另一個仍處於等待
    Lock.Release():解鎖並喚醒任何等待中的程序

  2. 原子操作指令
    CPU體系結構中提供了一些特殊的原子操作指令,這些指令把若干個操作合成一個原子操作,保證這些操作之間不會部分執行的狀態。

    • TS指令
      ==19==
    • 交換指令(交換記憶體中的兩個值)
      ==20==
  3. 使用TS指令實現自旋鎖
    ==21==
    ==22==

  4. 原子操作指令鎖的特徵
    ==23==

  5. 同步方法總結
    ==24==