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