進程間通信基本概念【操作系統】

進程間通信的目的:

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位哲學家同時進入餐廳,由於最多有四位哲學家就坐,則至少有一位哲學家拿到可兩根筷子.


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