操作系統進程同步

進程同步

兩種制約關係

間接相互制約關係:同處於一個系統中的進程,必然共享着某種系統資源。所謂間接相互制約即源於這種資源共享。例如,有兩個進程A和B,如果在A進程提出打印請求時,系統已將唯一的一臺打印機分配給了進程B,則此時進程A只能阻塞;一旦進程B將打印機釋放,才能使A進程由阻塞改爲就緒狀態。(進程互斥)
(就是兩個進程共同競爭一個資源,當A釋放了共享資源後B才能繼續進行)
在這裏插入圖片描述
直接相互制約關係:這種制約源於進程間的合作。例如C進程因得不到A進程的數據而阻塞。(進程同步)
(兩者是某種順序關係,A做完B才能繼續)
在這裏插入圖片描述

臨界資源

臨界資源:一次僅允許一個進程使用的資源。
許多物理設備,如輸入機、打印機、磁帶機等都具有這種性質。
軟件資源,如公用變量、數據、表格、隊列等也都具有這一特點。
諸進程之間應通過互斥方式,實現對臨界資源的共享。

臨界區

不論是硬件臨界資源,還是軟件臨界資源,多個進程必須互斥地對它進行訪問。
臨界區:每個進程中訪問臨界資源的那段代碼稱爲臨界區。
每個進程進入臨界區之前,應先對欲訪問的臨界資源進行檢查,看它是否正被訪問。如果此刻該臨界資源未被訪問,進程便可進入臨界區對該資源進行訪問,並設置它正被訪問的標誌;如果此刻該臨界資源正被某進程訪問,則本進程不能進入臨界區。
在這裏插入圖片描述

同步機制的四個準則

  1. 空閒讓進:當無進程處於臨界區時,應允許一個請求進入臨界區的進程進入臨界區;
  2. 忙則等待:當已有進程進入臨界區時,其他試圖進入臨界區的進程必須等待;
  3. 有限等待:對要求訪問臨界資源的進程,應保證在有限時間內能進入自己的臨界區,以免陷入“死等”狀態;
  4. 讓權等待:當進程不能進入自己的臨界區時,應立即釋放處理機,以免進程陷入“忙等”。

信號量機制

整型信號量

思想:定義一個整型量S,除初始化外,僅能通過兩個標準的原子操作wait(S)和signal(S)來訪問。

wait(S): {
				while S≤0;    /*do no-op*/
                 S--;
               }
signal(S): {
                    S++;
                  }


缺點:當s<=0時,會進入死循環,一直佔用CPU,浪費資源。因此,該機制並未遵循“讓權等待”的準則,而是使進程處於“忙等”的狀態。

記錄型信號量

思想:用整型變量value代表資源的數目。用進程鏈表L來鏈接等待訪問臨界資源的進程。

記錄型信號量的定義:
  typedef struct {
                     int value;
                      struct process_control_block *list;
                           }semphore;

臨界資源阻塞隊列:
在這裏插入圖片描述

記錄型信號量的P、V操作

wait(semaphare *S)
  {
    S->value--;
    if (S->value<0)  block(S->list);
   }
signal(semphore *S)
 {
     S->value++;
     if (S->value≤0) then wakeup(S->list);
  }

在這裏插入圖片描述

說明

S->value的初值表示系統中某類資源的數目,因而又稱爲資源信號量,對它的每次wait操作,意味着進程請求一個單位的該類資源,使系統中可供分配的資源數減少一個,因此S->value–;
每次執行完wait操作後,若S->value<0時,說明該類資源已分配完畢,因此進程應調用block原語,進行自我阻塞,放棄處理機,並插入到信號量鏈表S->list中。此時S->value的絕對值表示在該信號量鏈表中已阻塞進程的數目
每次執行signal操作表示資源數目加1,若加1後仍有S->value≤0時,則表示在該信號量鏈表中,仍有等待該資源的進程被阻塞,故還應調用wakeup原語,將S->list鏈表中的第一個等待進程喚醒
若S->value的初值爲1,表示只允許一個進程訪問臨界資源,此時的信號量轉化爲互斥信號量。

AND型信號量

思想:將進程在整個運行過程中需要的所有資源,一次性全部地分配給進程,待進程使用完成後再一起釋放。只要尚有一個資源未能分配給進程,其他所有可能爲之分配的資源,也不分配給它。亦即,對若干個臨界資源的分配,採取原子操作方式:要麼全部分配給進程,要麼一個也不分配

Swait(S1,S2,,Sn)
{   while (TRUE)  
    { 
    if (S1≥1&&&&Sn≥1){
     for (i=1;i<=n;i++)
          Si--;
     break;
      }
else {
     place the process in the waiting queue associated with the first Si found with Si<1, and set the program count of this process to the beginning of Swait operation
     將進程放入第一個Si<ti的等待隊列中,並且將程序指針指向該進程的Swait操作開始處;
       }
   }
}

Ssginal(S1,S2,,Sn)
  while (TRUE){
 for(i:=1;i<=n;i++){ 
    Si++;
    remove all the process waiting in the queue associated with Si into the ready queue
    將與Si 相關的等待隊列中的進程移到就緒隊列
   }
  }
}

在這裏插入圖片描述

信號量集

思想:若進程一次需要申請多類臨界資源,則在進行臨界資源分配時,先測試各類臨界資源是否大於其下限值。若低於下限值,則不予分配。
以下的程序中,S爲信號量,d爲需求值,t爲下限值。

Swait(S1,t1,d1,,Sn,tn,dn)
   while (TRUE){
 if (S1≥t1 &&&& Sn≥tn )
        for (i=1;i<=n;i++)   Si:=Si-di;
        break;
}         
else { 
        Place the executing process in the waiting queue of the first Si with Si<ti and set its program counter to the beginning of the Swait Operation.
        將正在執行的進程移入第一個Si<ti的等待隊列中,並將程序指針指向該進程中Swait操作開始處
   }
 }
}

Ssignal(Si,di,,Sn,dn)
{ while (TRUE)
    {   
       for (i=1;i<=n;i++) {
        Si:=Si+di;
        Remove all the process waiting in the queue associated with Si into the ready queue
        將與Si相關的等待隊列中的所有進程移到就緒隊列
     }
   }
}

信號量機制的應用

實現進程互斥

爲使得多個進程能互斥地訪問某臨界資源,只需爲該資源設置一互斥信號量mutex,並設其初始值爲1,然後將各進程訪問該資源的臨界區CS置於wait(mutex)和signal(mutex)操作之間即可。
在這裏插入圖片描述

實現前趨

在這裏插入圖片描述
技巧:後進程實現P(wait)操作,前進程實現V(signal)操作。

大家覺得有幫助的請點個贊啊👍

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章