天天看點

程序間通信基本概念【作業系統】

程序間通信的目的:

1.資料傳遞

2.資源共享

3.通知事件

程序間通信的發展曆史:

1.管道

2.SystemV

3.POSIX(可移植作業系統接口)

管道:

1.匿名管道pipe

2.命名管道

SysV IPC:

1.消息隊列

2.共享記憶體

3.信号量

POSIX IPC:

1.消息隊列

2.共享記憶體

3.信号量

4.互斥量

5.條件變量

6.讀寫鎖

Socket :(程序間通信)

程序間共享的幾種方式:

程式間通信基本概念【作業系統】

1.左邊兩個程序共享存留于檔案系統中某個檔案上的某些資訊,為了通路這些資訊,每個程序都得穿越核心如(read、write、lseek等)。當一個檔案有待更新時,某種形式的同步是需要的,這樣既可以保護多個寫入者,防止互相串擾,也可以保護一個或多個讀者,防止寫入者的幹擾。

2.中間兩個程序共享駐留于核心中的某些資訊。管道是這種共享類型的典型例子。現在通路共享資訊的每次操作都涉及向核心的一個系統調用。

3.右邊兩個程序有一個雙方都能通路的共享記憶體區。每個程序一旦設定号該共享記憶體區,就能根本不涉及核心而通路其中的資料,共享該記憶體區的程序需要某種形式的同步

IPC對象的持續性:

1.随程序持續性的 IPC   :一直存在到打開着該對象的最後一個程序關閉該對象為止。如管道和FIFO;

2.随核心持續性的IPC  :一直存在到得喝重新自舉或顯式的删除該對象為止。如SystemV 消息隊列和共享記憶體區。 Posix消息隊列和共享記憶體區。

3.随檔案系統持續性的IPC :一直存在到顯式的删除該對象為止。即使記憶體重新自舉了,該對象還是保持其值。Posix消息隊列和共享記憶體區。

程序同步:(司機-售票員)兩個或多個程序需要互相配合才能完成一項任務

程序互斥:(賣票,提款等)由于各個程序都要通路共享資源,而且這些資源需要排他使用,是以各個程序間需要競争使用這些資源,這種關系就叫程序互斥

司機售票員問題:

司機:

while(1)
{
    啟動車輛;

    正常行駛;

    到站停車;
}
           

售票員:

while(1)
{
    關門;

    賣票;

    開門;
}
           

賣票:

售票機:

while(p > 0)                  //p為還有的票數
{
   p--;
}
           

信号量機制:(計數器)

PV操作提出者:迪傑斯特拉(Dijkstra)

信号量:

互斥:P操作和V操作在同一個程序中

同步:P操作和V操作在不同的程序中

信号量的結構體模型:

struct semaphore{
        int value;                               //資源數目
        struct task_struct *ptr;                 //等待該信号量,處于等待狀态
};
           

信号量值的含義:

S > 0:表示S有這麼多的資源可以使用

S = 0:表示沒有資源可以使用,也沒有程序在該信号量上等待資源

S < 0:表示有|S|個程序在等待該資源

P原語:
	p(s)
	{
		s.value--;			
		{
			将該程序隻為等待狀态
			将該程序的task_struct插入到相應的等待隊列
		}
	}
           
V原語:
	v(s)
	{
		s.value++;
		if(s.value <= 0)
		{
			将等待隊列上的程序喚醒(一般為隊頭程序)
			将其改為就緒狀态
			放入就緒隊列
		}
	}
           

PV原語表示司機售票員問題:

程式間通信基本概念【作業系統】

售票機:Sem(1)

while(1)

{

    P(Sem);

    if(p > 0)    p--;

    V(Sem);

}

程式間通信基本概念【作業系統】

死鎖:是指兩個或兩個以上的程序(或線程)在執行過程中,因争奪資源而造成的一種互相等待的現象,若無外力作用,它們都将無法推進下去。此時稱系統處于死鎖狀态或系統産生了死鎖,這些永遠在互相等待的程序稱為死鎖程序。

死鎖發生的四個條件:

1、互斥條件:程序對資源的通路是排他性的,如果一個線程對占用了某資源,那麼其他線程必須處于等待狀态,直到資源被釋放。

2、請求和保持條件:程序T1至少已經保持了一個資源R1占用,但又提出對另一個資源R2請求,而此時,資源R2被其他程序T2占用,于是該程序T1也必須等待,但又對自己保持的資源R1不釋放。

3、不剝奪條件:程序已獲得的資源,在未使用完之前,不能被其他程序剝奪,隻能在使用完以後由自己釋放。

4、環路等待條件:在死鎖發生時,必然存在一個“程序-資源環形鍊”,即:{p0,p1,p2,...pn},程序p0(或線程)等待p1占用的資源,p1等待p2占用的資源,pn等待p0占用的資源。(最直覺的了解是,p0等待p1占用的資源,而p1而在等待p0占用的資源,于是兩個程序就互相等待)

預防死鎖:

1.破壞請求保持條件。

1> 一次性配置設定給程序它在運作期間所需要的全部資源。缺點:造成資源的浪費

2> 允許一個程序隻獲得運作初期所需要的資源後,便開始運作,程序運作過程中再逐漸釋放已配置設定給自己的,并且已用畢的全部資源,然後請求新的所需要的資源。

2.破壞不可搶占條件。

當一個程序保持了某些不可被強占資源的程序,提出新的資源請求而不能被滿足時,它必須釋放已經保持得所有資源,待以後需要時再重新申請。也就是說已占有的資源被暫時的釋放,或者說被搶占

3.破壞循環等待條件

規定每個程序必須按序請求資源

一般的死鎖避免算法:(銀行家算法)

銀行家算法:

1.當顧客的資金需求小于銀行家現有的資金總量,接納該客戶

2.顧客可以分期貸款,但貸款總額不能超過最大需求量

3.當銀行家現有的資金不能滿足顧客的需求,可以推遲支付,但總能在有限的時間内讓顧客得到貸款

4.當顧客使用完全部貸款,一定能夠在有限的時間内歸還所有資金

哲學家就餐問題:典型的死鎖問題

while(1)
{
	思考;
	if(餓)
	{
		拿左筷子;
		拿右筷子;

		吃;
		放左筷子;
		放右筷子;
	}
}
           

1. 為了克服死鎖風險,可以再添加5根筷子,或者教會哲學家僅用一根筷子吃飯。

2. 另一種方法是添加一個服務員,他隻允許4位哲學家同時進入餐廳,由于最多有四位哲學家就坐,則至少有一位哲學家拿到可兩根筷子.

繼續閱讀