|
信號(hào)量機(jī)制是一種卓有成效的進(jìn)程互斥同步工具。這里只介紹記錄型信號(hào)量機(jī)制,它可以有效的解決CPU“忙等”的問題,實(shí)現(xiàn)互斥。
記錄型信號(hào)量機(jī)制的數(shù)據(jù)結(jié)構(gòu)如下(看不懂那些字母是什么其實(shí)沒有關(guān)系):
type semaphore=record value:integer; (下文傳說中的S) L: list of process;(排隊(duì)使用的進(jìn)程要待的阻塞隊(duì)列) end;
這里需要注意記錄型信號(hào)量S的整形分量value的值的物理含義,表示該類資源可用的數(shù)目,也可以說是執(zhí)行P操作而不會(huì)被阻塞的進(jìn)程的數(shù)目,一般為<=1,因?yàn)檫@里是進(jìn)程互斥(但是也可以大于1),等于1時(shí),表示該資源可用,等于0時(shí),表示該資源正在被使用,而且沒有進(jìn)程被阻塞,但是當(dāng)期數(shù)值小于0時(shí),其絕對(duì)值表示信號(hào)量S的阻塞隊(duì)列中的進(jìn)程數(shù)。L表示進(jìn)程的阻塞隊(duì)列。
記錄型信號(hào)機(jī)制的實(shí)現(xiàn)伴隨著P操作和V操作,P操作指的是測(cè)試,V操作指的是增加,不要問我為啥叫PV,我只能說來源于荷蘭語(yǔ)。一般P操作要伴隨著V操作,二者成雙成對(duì)出現(xiàn)。
那么我們來看看P操作和V操作到底是什么,那么神奇:
P的原語(yǔ)操作可以描述為: procedure P(var s:semaphore); begin s.value:=s.value-1;(將信號(hào)量值減1) if s.value<0 then block(s.L);(若信號(hào)量值小于0,則調(diào)用阻塞原語(yǔ)阻塞自己,插入到阻塞隊(duì)列中去) end;
V的原語(yǔ)操作可以描述為: procedure P(var s:semaphore); begin s.value:=s.value+1;(將信號(hào)量值加1) if s.value<0 then wakeup(s.L);(若信號(hào)量值小于等于0,則調(diào)用喚醒原語(yǔ)從阻塞隊(duì)列中喚醒一個(gè)進(jìn)程)
舉個(gè)實(shí)際的栗子: 用P,V操作實(shí)現(xiàn)火車互聯(lián)網(wǎng)定票系統(tǒng)在北京,天津兩地的兩個(gè)終端售票進(jìn)程發(fā)售同一班次車票的過程。 (1) 根據(jù)顧客要求找到公共數(shù)據(jù)單元 (2) P(S); (3) 把Pk的值讀到工作寄存器R1中;(進(jìn)程的臨界區(qū)) (4) 根據(jù)顧客訂票數(shù)修改R1;(進(jìn)程的臨界區(qū)) (5) 將R1的值寫到Pk中;(進(jìn)程的臨界區(qū)) (6) V(S); (7) 售出顧客所定的票,返回;
例如北京的售票區(qū)搶先執(zhí)行并且進(jìn)入自己的臨界區(qū),這時(shí)輪到天津區(qū)執(zhí)行進(jìn)程,也要求進(jìn)入臨界區(qū),執(zhí)行P(S),但是因?yàn)楸本┮呀?jīng)在臨界區(qū)中,執(zhí)行完P(guān)了,此時(shí)的信號(hào)量S的值已經(jīng)從1減為0,然后因?yàn)樘旖蚴燮眻?zhí)行P(S),此時(shí)P(S)的值變?yōu)?1,導(dǎo)致自己阻塞,直到北京之行完V(S),使得S的值變?yōu)?,然后天津從阻塞隊(duì)列中喚醒,當(dāng)它再次訪問公共票據(jù)單元時(shí),數(shù)據(jù)已經(jīng)被背景改過了,然后就實(shí)現(xiàn)了互斥。
|
|
|