1.什么是PV操作
??PV操作是由P操作原語和V操作原語組成(原語是不可[中斷的過程),操作對象是信號量。具體的:
??P(S):① 將信號量S的值減1,即S=S-1;② 如果S>=0,則該進(jìn)程繼續(xù)執(zhí)行;否則進(jìn)程進(jìn)入等待隊列,置為等待狀態(tài)。
??V(S):① 將信號量S的值加1,即S=S+1;② 如果S>0,則該進(jìn)程繼續(xù)執(zhí)行;否則釋放等待隊列中第一個等待信號量的進(jìn)程。(因為將信號量加1后仍然不大于0,則表示等待隊列中有阻塞的進(jìn)程。)
2.PV操作的意義
??使用PV操作和信號量可以實(shí)現(xiàn)進(jìn)程間的同步和互斥。
3.什么是信號量
??信號量(semaphore)的數(shù)據(jù)結(jié)構(gòu)為一個值和一個指針,指針指向等待該信號的下一個進(jìn)程。信號量的值與相應(yīng)資源的使用情況有關(guān)。當(dāng)信號量的值大于0時,表示當(dāng)前可用資源的數(shù)量;當(dāng)信號量的值小于0時,其絕對值表示當(dāng)前阻塞等待使用該資源的進(jìn)程個數(shù)。(信號量值只能用PV操作來改變。)
??一般的,當(dāng)信號量S>=0時,S表示可用資源的數(shù)量。執(zhí)行一次P操作意味著請求分配一個單位資源,因此S的值減1;當(dāng)S<0時,表示已經(jīng)沒有可用資源,請求者必須阻塞等待別的進(jìn)程釋放該類資源才能繼續(xù)運(yùn)行。而執(zhí)行一個V操作意味著釋放一個單位資源,因此S的值加1;若S<=0,表示此刻有進(jìn)程正在阻塞等待該資源,因此要喚醒一個等待狀態(tài)的進(jìn)程,使之運(yùn)行下去。
4.PV操作實(shí)例—生產(chǎn)者消費(fèi)者問題
4.1 一個生產(chǎn)者,一個消費(fèi)者,公用一個緩沖區(qū)
(1)定義兩個同步信號量
??emtpy表示緩沖區(qū)是否為空,初始值為1;full表示緩沖區(qū)是否為滿,初始值為0。
(2)生產(chǎn)者-消費(fèi)者進(jìn)程偽代碼
while(TRUE)
{
生產(chǎn)一個產(chǎn)品;
P(empty);
將一個產(chǎn)品送入緩沖區(qū);
V(full);
}
//消費(fèi)者進(jìn)程
while(TRUE)
{
P(full);
從緩沖區(qū)取出一個產(chǎn)品;
V(empty);
消費(fèi)取出的產(chǎn)品;
}
4.2 一個生產(chǎn)者,一個消費(fèi)者,公用n個環(huán)形緩沖區(qū)
(1)定義兩個同步信息量
??empty表示緩沖區(qū)是否為空,初始值為n;full表示緩沖區(qū)是否為滿,初始值為0。
??設(shè)緩沖區(qū)的編號為1~n-1,定義兩個指針in和out,分別是生產(chǎn)者和消費(fèi)者使用的指針,指向下一個可用緩沖區(qū)。
(2)生產(chǎn)者-消費(fèi)者進(jìn)程偽代碼
//生產(chǎn)者進(jìn)程
while(TRUE)
{
生產(chǎn)一個產(chǎn)品;
P(empty);
將一個產(chǎn)品送入緩沖區(qū)in;
in = (in+1) mod n;
V(full);
}
//消費(fèi)者進(jìn)程
while(TRUE)
{
P(full);
從緩沖區(qū)(out)取出一個產(chǎn)品;
out = (out+1) mod n;
V(empty);
消費(fèi)取出的產(chǎn)品;
}
4.3 多個生產(chǎn)者,多個消費(fèi)者,公用n個環(huán)形緩沖區(qū)
(1)定義兩個同步信息量
??empty表示緩沖區(qū)是否為空,初始值為n;
??full表示緩沖區(qū)是否為滿,初始值為0;
??mutex1表示生產(chǎn)者進(jìn)程之間的互斥信號量;
??mutex2表示消費(fèi)者進(jìn)程之間的互斥信號量;
??設(shè)緩沖區(qū)的編號為1~n-1,定義兩個指針in和out,分別是生產(chǎn)者和消費(fèi)者使用的指針,指向下一個可用緩沖區(qū)。
//生產(chǎn)者進(jìn)程
while(TRUE)
{
生產(chǎn)一個產(chǎn)品;
P(empty);
P(mutex1);
將一個產(chǎn)品送入緩沖區(qū)in;
in = (in+1) mod n;
V(mutex1);
V(full);
}
//消費(fèi)者進(jìn)程
while(TRUE)
{
P(full);
P(mutex2);
從緩沖區(qū)(out)取出一個產(chǎn)品;
out = (out+1) mod n;
V(empty);
V(mutex2);
消費(fèi)取出的產(chǎn)品;
}