1. 程式人生 > >通過硬體的支援實現互斥

通過硬體的支援實現互斥

一、中斷禁用

   單處理機:在單處理機中,併發程序不能重疊,只能交替,作業系統通過中斷來實現程序的交替,那麼就會存在一個問題,當一個程序A執行到臨界區時發生了中斷,另一個程序B執行,程序B也可以執行臨界區程式碼,這樣就改變了臨界資源,當程序A再接著中斷的位置執行時相關資料有可能已經被程序B修改,出現錯誤。

      這個問題可以通過禁用中斷來解決,禁用中斷和啟用中斷都是原語操作。通過這個方法來實現互斥如下:

while(true)
{
    /* 禁用中斷 */
    /* 臨界區 */
    /* 啟用中斷 */
    /* 其餘部分 */
}

 中斷禁用的優缺點:

優點:臨界區不可被中斷,故此可以保證互斥

缺點:由於處理器被限制於只能交替執行程式,因此執行的效率有明顯的降低 

二、專用機器指令  

  多處理機:在多處理機配置中,幾個處理器共享記憶體,處理器間的行為是對等的,處理器之間沒有支援互斥的中斷機制。在硬體級別上,對儲存單元的訪問排斥對相同單元的其他訪問。基於這一點,處理器的設計者提出了一些機器指令,用於保證兩個動作的原子性,即某一時刻只能有一個臨界區程式碼訪問臨界資源。兩種最常見的指令是:比較和交換指令交換指令

  • 比較和交換指令如下:
int compare_and_swap(int *word, int testval, int newval)
{
    int oldval;
    oldval = *word;
    if(oldval == testval) *word = newval;
    return oldval;
}

示例:

const int n = /* 程序個數 */
int bolt;
void p(int i)
{
    while(true)
    {
        while(compare_and_swap(bolt, 0, 1) == 1)
        {
            /* 不做任何事 */
        }
        /* 臨界區 */
        bolt = 0;
        /* 其餘部分 */
    }
}

void main()
{
    bolt = 0;
    parbegin (p(1), p(2), ... ,p(n));
}

    程序開始,bolt = 0當某一個程序A率先執行比較和交換指令時可以通過,通過之後便將bolt改為1,而測試值是0,因此其他程序執行比較和交換指令時不能通過,處於忙等待狀態(在程序得到臨界區訪問權之前,它只能繼續執行測試變數的指令來得到訪問權,除此之外不能做其他事情),當程序A執行完臨界區之後又將bolt值改為0, 則將會有一個程序測試通過,往復執行,即可保證某一時刻只有一個臨界區程式碼訪問臨界資源。

  • 交換指令如下:
void exchange(int *register, int *memory)
{
    int temp;
    temp = *memory;
    *memory = *register;
    *register = temp;
}

示例:

int const n = /* 程序個數 */;
int bolt;
void p(int i)
{
    int keyi = 1;
    while(true)
    {
        do exchange(&keyi, &bolt)
        while(keyi != 0)
        {
            /* 臨界區 */
        }
        bolt = 0;
        /* 其他部分 */
    }
}

void main()
{
    bolt = 0;
    parbegin (p(1), p(2), ... ,p(n));
}

     程序開始,bolt = 0當某一個程序A率先執行交換指令時可以通過,通過之後便將bolt改為1,因此其他程序執行交換指令時bolt = 1,通過交換將keyi置為1,則將一直處於while迴圈中,無法執行下邊臨界區。當程序A執行完臨界區之後又將bolt值改為0, 則將會有一個程序測試通過,往復執行,即可保證某一時刻只有一個臨界區程式碼訪問臨界資源。

機器指令方法的優缺點:

優點

  • 適用於在單處理器或共享記憶體的多處理器上的任何數目的程序
  • 非常簡單且易於證明
  • 可用於支援多個臨界區,每個臨界區可以用它自己的變數定義

缺點

  • 使用了忙等待:因此當一個程序正在等待進入臨界區時,它會繼續消耗處理器時間
  • 可能飢餓:當一個程序離開一個臨界區並且有多個程序正在等待時,選擇哪一個程序是任意的,因此某些程序可能被無限拒絕進入。
  • 可能死鎖:當某個程序通過專門指令時,在臨界區中發生中斷將有可能發生死鎖。