專利名稱:在多任務(wù)操作系統(tǒng)中解決任務(wù)死鎖的方法
技術(shù)領(lǐng)域:
本發(fā)明提出一種在多任務(wù)操作系統(tǒng)中解決任務(wù)死鎖的方法,它是基于將可能導(dǎo)致死鎖的有限資源擴(kuò)展為無(wú)限資源的機(jī)制。
背景技術(shù):
在多任務(wù)操作系統(tǒng)中,通常提供了任務(wù)間互發(fā)消息的機(jī)制來(lái)實(shí)現(xiàn)任務(wù)間通信,如VxWorks、pSos等商用嵌入式操作系統(tǒng)。這種機(jī)制的實(shí)現(xiàn)基于消息隊(duì)列。用戶可以為某個(gè)任務(wù)創(chuàng)建一個(gè)消息隊(duì)列,并守候在這個(gè)消息隊(duì)列上,要和該任務(wù)通信的其它任務(wù)可以將消息發(fā)送到這個(gè)消息隊(duì)列上,這樣就實(shí)現(xiàn)了任務(wù)間的通信。
多任務(wù)操作系統(tǒng)都對(duì)消息隊(duì)列賦予了如下操作發(fā)送消息到某消息隊(duì)列;從某消息隊(duì)列接收消息。并且這些操作都具有延時(shí)的功能,包括0延時(shí)和永久等待。如果是延時(shí)一段時(shí)間,發(fā)送者(或接收者)如果不能立即發(fā)送成功(或接收到消息),則發(fā)送者(或接收者)將會(huì)被阻塞一段時(shí)間再試圖發(fā)送(或接收),這時(shí)不論發(fā)送成功(或接收到消息)與否,發(fā)送者(或接收者)都將繼續(xù)往下運(yùn)行。如果是0延時(shí),則發(fā)送者(或接收者)不論發(fā)送成功(或接收到消息)與否,都將繼續(xù)往下運(yùn)行。如果是永久等待,則發(fā)送者(或接收者)只有發(fā)送成功(或接收到消息),才會(huì)繼續(xù)往下運(yùn)行,否則將會(huì)一直阻塞。
在創(chuàng)建消息隊(duì)列時(shí),需要為消息隊(duì)列指定一個(gè)最大長(zhǎng)度,即可以容納的消息的最大數(shù)目。在通信軟件中,任務(wù)之間常常是通過(guò)大量的消息進(jìn)行交互的。通常每個(gè)任務(wù)都有它自己的消息隊(duì)列,該任務(wù)守候在它的消息隊(duì)列上等候接收消息然后進(jìn)行處理。如果在發(fā)送消息時(shí)采用永久等待的方式,就很容易導(dǎo)致兩個(gè)甚至多個(gè)任務(wù)因?yàn)榛グl(fā)消息而導(dǎo)致死鎖。例如任務(wù)A和任務(wù)B,它們的消息隊(duì)列長(zhǎng)度為N。在某個(gè)時(shí)刻任務(wù)A和任務(wù)B的消息隊(duì)列中已經(jīng)存儲(chǔ)了N-1個(gè)消息(如圖1所示),這時(shí)有一個(gè)任務(wù)C向任務(wù)A和B各發(fā)送了一個(gè)消息,導(dǎo)致任務(wù)A和任務(wù)B的消息隊(duì)列全滿了(如圖2所示)。任務(wù)A得到運(yùn)行后,向任務(wù)B發(fā)送一個(gè)消息,但是由于任務(wù)B的消息隊(duì)列已滿,因此任務(wù)A就進(jìn)入阻塞狀態(tài);而這時(shí)任務(wù)B得到運(yùn)行后,向任務(wù)A也發(fā)送一條消息,由于同樣的原因,任務(wù)B也進(jìn)入阻塞狀態(tài)(如圖3所示)。從而,任務(wù)A和B因?yàn)榛グl(fā)消息導(dǎo)致了死鎖,再也得不到運(yùn)行。這種問(wèn)題對(duì)于軟件系統(tǒng)來(lái)說(shuō)是致命的。
為了解決這個(gè)問(wèn)題,有些通信軟件采用了0延時(shí)或者延時(shí)一段時(shí)間的方法進(jìn)行發(fā)送。如果發(fā)送不成功,就將發(fā)送的消息丟棄。這樣的方法雖然能夠避免死鎖,但是以丟掉消息作為代價(jià)的,這樣會(huì)增加系統(tǒng)的不可靠性。
針對(duì)這些問(wèn)題,本發(fā)明提出了一種可靠的方法來(lái)解決任務(wù)間因互發(fā)消息而導(dǎo)致的死鎖。
發(fā)明內(nèi)容
本發(fā)明所要解決的技術(shù)問(wèn)題在于提供一種既不丟棄消息又能解決任務(wù)間因互發(fā)消息而造成死鎖的方法。
本發(fā)明提出一種在多任務(wù)操作系統(tǒng)中解決任務(wù)死鎖的方法,它是基于將可能導(dǎo)致死鎖的有限資源擴(kuò)展為無(wú)限資源的機(jī)制。本發(fā)明通過(guò)在消息控制頭中增加一個(gè)指向下一個(gè)消息的指針來(lái)實(shí)現(xiàn)對(duì)消息的緩存,形成緩存鏈表;通過(guò)發(fā)送者在發(fā)送消息時(shí)查看本身所在的任務(wù)的消息隊(duì)列是否為滿,若滿則取出一條消息放入緩存鏈表的方式來(lái)確保任務(wù)間不會(huì)出現(xiàn)因互發(fā)消息導(dǎo)致死鎖。
本發(fā)明包括以下步驟(1)對(duì)系統(tǒng)進(jìn)行初始化,包括創(chuàng)建消息隊(duì)列、創(chuàng)建任務(wù)、初始化緩存鏈表;(2)發(fā)送者發(fā)送消息到接收任務(wù)的消息隊(duì)列,發(fā)送者如果在發(fā)送消息時(shí)失敗,首先查看本身所在的任務(wù)的消息隊(duì)列是否為滿,若為滿,則取出一條消息放入緩存鏈表,使得自己的消息隊(duì)列不滿;(3)接收者在自己的消息隊(duì)列上接收消息,接收者首先處理緩沖鏈表中的消息,將緩沖鏈表中的消息處理完畢后,才能處理自己的消息隊(duì)列中的消息。
采用本發(fā)明中所述方法,可以避免因系統(tǒng)中各任務(wù)互發(fā)消息而引起的死鎖,并且可以不丟失消息。為系統(tǒng)的穩(wěn)定性運(yùn)行提供了保障,并且減少上層應(yīng)用軟件的復(fù)雜度,使得軟件更易實(shí)現(xiàn)。對(duì)于系統(tǒng)中突發(fā)的消息流,可以進(jìn)行暫時(shí)的緩沖,增強(qiáng)了系統(tǒng)的健壯性。
以下是對(duì)附圖的說(shuō)明圖1是任務(wù)A和任務(wù)B的消息隊(duì)列都為N-1時(shí)的狀態(tài)。
圖2是任務(wù)A和任務(wù)B的消息隊(duì)列都為N時(shí)的狀態(tài)圖3是任務(wù)A和任務(wù)B發(fā)生死鎖時(shí)的情形。
圖4是初始化流程。
圖5是發(fā)送消息到接收任務(wù)的消息隊(duì)列的流程。
圖6是在消息隊(duì)列上接收消息的流程。
具體實(shí)施例方式
下面將結(jié)合附圖與具體實(shí)施方式
對(duì)本發(fā)明做進(jìn)一步的詳細(xì)描述為了實(shí)現(xiàn)消息的無(wú)限緩存,我們采用了鏈表的方式將要緩存的消息連接起來(lái)。因此,數(shù)據(jù)結(jié)構(gòu)的組織采用了如下的方式所有的消息都需要一個(gè)消息控制頭,緊跟著消息控制頭后面的是消息體。在消息控制頭中有一個(gè)指針,指向下一個(gè)消息。我們利用這個(gè)指針將要緩存的消息連接起來(lái),形成緩存鏈表,從而實(shí)現(xiàn)了消息的無(wú)限緩存。這是保證解決任務(wù)間互發(fā)消息而導(dǎo)致死鎖的前提。因?yàn)樗鼘?shí)質(zhì)上是將任務(wù)消息隊(duì)列的長(zhǎng)度擴(kuò)展為無(wú)限長(zhǎng),解決了資源問(wèn)題。
為了使系統(tǒng)正常運(yùn)行,需要一些必要的初始化工作。包括創(chuàng)建消息隊(duì)列、創(chuàng)建發(fā)送任務(wù)和接收任務(wù)、初始化緩存鏈表等。消息隊(duì)列既可以使用操作系統(tǒng)創(chuàng)建的消息隊(duì)列,也可以用用戶自己的方法來(lái)創(chuàng)建消息隊(duì)列。只要消息對(duì)列的長(zhǎng)度是有限的,本方法都是適用的。本文中提到的用戶自己創(chuàng)建隊(duì)列函數(shù)、消息接受函數(shù)和發(fā)送函數(shù)的功能是和系統(tǒng)的隊(duì)列函數(shù)、消息接收函數(shù)和發(fā)送函數(shù)的功能一致的。
初始化部分的實(shí)施步驟如下
1、調(diào)用系統(tǒng)函數(shù)或使用用戶創(chuàng)建的隊(duì)列函數(shù),為需要接收消息的任務(wù),按照指定的隊(duì)列長(zhǎng)度創(chuàng)建消息隊(duì)列。
2、創(chuàng)建系統(tǒng)中的任務(wù),包括接收任務(wù)和發(fā)送任務(wù)。
3、初始化各接收任務(wù)的消息緩存鏈表為空。
初始化部分的實(shí)施流程如圖4所示。
在進(jìn)行完相應(yīng)的初始化工作后,系統(tǒng)進(jìn)入工作狀態(tài)。這時(shí)任務(wù)間就可以通過(guò)互發(fā)消息進(jìn)行通信了。為了避免原來(lái)的因?yàn)槿蝿?wù)間互發(fā)消息而導(dǎo)致的死鎖問(wèn)題,我們必須修改通常的發(fā)送消息流程簡(jiǎn)單調(diào)用系統(tǒng)的或用戶自己的發(fā)送消息函數(shù)直接進(jìn)行發(fā)送。主要的改變就是調(diào)用系統(tǒng)發(fā)送消息函數(shù)或用戶自己的發(fā)送消息函數(shù)以0延時(shí)的方式發(fā)送消息到接收任務(wù)的消息隊(duì)列。如果發(fā)送不成功,則先查看發(fā)送者本身的消息隊(duì)列是否是滿的。如果滿,則發(fā)送者要調(diào)用系統(tǒng)接收函數(shù)或用戶自己的消息接收函數(shù)從自己的消息隊(duì)列中接收一條消息,插入到緩沖鏈表中,以保證發(fā)送者的消息隊(duì)列不會(huì)永遠(yuǎn)為滿。這個(gè)步驟是保證任務(wù)間不發(fā)生死鎖的關(guān)鍵。
發(fā)送者發(fā)送消息到接收任務(wù)的消息隊(duì)列的實(shí)施步驟如下1、用系統(tǒng)的或用戶自己的發(fā)送消息函數(shù),以0延時(shí)的方式發(fā)送消息到接收任務(wù)的消息隊(duì)列。如果發(fā)送成功,轉(zhuǎn)到5;否則,轉(zhuǎn)到2。
2、查看發(fā)送者所在任務(wù)的消息隊(duì)列中消息數(shù)目。如果消息數(shù)目等于該消息隊(duì)列的長(zhǎng)度,則繼續(xù);否則,轉(zhuǎn)到4。
3、調(diào)用系統(tǒng)的或用戶自己的接收消息函數(shù),以永久等待的方式從發(fā)送者的消息隊(duì)列上接收一條消息,并將該消息插入緩存消息形成的鏈表。在該步中,接收到的消息可能是一個(gè)消息串,即有若干條消息通過(guò)消息控制頭中的指向下一個(gè)消息的指針連接起來(lái)。若為消息串,則需要將該消息串的尾部作為消息緩存鏈表的尾部。否則將該消息作為緩存鏈表的尾部。該步驟的目的是保證每個(gè)消息隊(duì)列不能永遠(yuǎn)為滿的狀態(tài)。
4、將發(fā)送者所在的任務(wù)延時(shí)一段時(shí)間,轉(zhuǎn)到1。該步驟的目的是為了防止發(fā)送任務(wù)長(zhǎng)時(shí)間占用CPU資源,使得其它任務(wù)有得到調(diào)度的機(jī)會(huì),能夠盡快處理自己的消息。
5、結(jié)束發(fā)送。
發(fā)送者發(fā)送消息到接收任務(wù)的消息隊(duì)列的實(shí)施流程如圖5所示。
由于在消息發(fā)送過(guò)程中,可能因?yàn)闀簳r(shí)發(fā)送不了消息而將自己的消息隊(duì)列中的消息取出進(jìn)行緩存,所以在緩存鏈表中可能會(huì)有一些消息。為了保證消息的有序性,我們需要優(yōu)先處理這些消息。因此,在接收消息的過(guò)程中,首先要查看接收者的緩存鏈表中是否有消息,如果有,則優(yōu)先處理這些消息。將所有的緩存消息處理完畢后,才能處理自己消息隊(duì)列上的消息。這種方法保證了消息被有序處理。
接收者在自己的消息隊(duì)列上接收消息的實(shí)施步驟如下1、查看緩存的消息鏈表是否為空。如果不為空,則繼續(xù);否則,轉(zhuǎn)到3。這一步保證了接收任務(wù)接收到的消息能夠被有序地處理。
2、從鏈表的頭部取出消息,進(jìn)行處理,轉(zhuǎn)到1。
3、用系統(tǒng)的或用戶自己的接收消息函數(shù),以永久等待的方式守候在該任務(wù)的消息隊(duì)列上。對(duì)接收消息進(jìn)行處理后,轉(zhuǎn)到1。
接收者在自己的消息隊(duì)列上接收消息的實(shí)施流程如圖6所示。
通過(guò)以上三部分的處理后,我們就可以保證在多任務(wù)操作系統(tǒng)中,任務(wù)不會(huì)因?yàn)榛グl(fā)消息而導(dǎo)致死鎖,也不用擔(dān)心消息會(huì)被丟棄而引起系統(tǒng)不穩(wěn)定的現(xiàn)象的發(fā)生,為系統(tǒng)的穩(wěn)定運(yùn)行提供了保障。相對(duì)于發(fā)送不成功丟棄消息的方法而言,上層應(yīng)用不需要考慮發(fā)送消息不成功時(shí)如何處理等額外的工作,因此減少了軟件的復(fù)雜度,使得軟件更易實(shí)現(xiàn)。采用了本發(fā)明中的方法,對(duì)于系統(tǒng)中突發(fā)的消息流,可以進(jìn)行暫時(shí)的緩沖,增強(qiáng)了系統(tǒng)的健壯性。
權(quán)利要求
1.一種在多任務(wù)操作系統(tǒng)中解決任務(wù)死鎖的方法,其特征在于,包括以下步驟(1)對(duì)系統(tǒng)進(jìn)行初始化,包括創(chuàng)建消息隊(duì)列、創(chuàng)建任務(wù)、初始化緩存鏈表;(2)發(fā)送者發(fā)送消息到接收任務(wù)的消息隊(duì)列,發(fā)送者如果在發(fā)送消息時(shí)失敗,首先查看本身所在的任務(wù)的消息隊(duì)列是否為滿,若為滿,則取出一條消息放入緩存鏈表,使得自己的消息隊(duì)列不滿;(3)接收者在自己的消息隊(duì)列上接收消啟,接收者首先處理緩沖鏈表中的消息,將緩沖鏈表中的消息處理完畢后,才能處理自己的消息隊(duì)列中的消息。
2.根據(jù)權(quán)利要求1所述的方法,其特征在于步驟(1)中所述的創(chuàng)建消息隊(duì)列是通過(guò)調(diào)用系統(tǒng)函數(shù)或使用用戶創(chuàng)建的隊(duì)列函數(shù),為需要接收消息的任務(wù),按照指定的隊(duì)列長(zhǎng)度創(chuàng)建消息隊(duì)列。
3.根據(jù)權(quán)利要求1所述的方法,其特征在于步驟(1)中所述的創(chuàng)建任務(wù)包括創(chuàng)建系統(tǒng)中的接收任務(wù)和發(fā)送任務(wù)。
4.根據(jù)權(quán)利要求1所述的方法,其特征在于步驟(2)中的發(fā)送消息到接收任務(wù)的消息隊(duì)列是通過(guò)調(diào)用系統(tǒng)發(fā)送消息函數(shù)或用戶自己的發(fā)送消息函數(shù)以0延時(shí)的方式發(fā)送。
5.根據(jù)權(quán)利要求1所述的方法,其特征在于通過(guò)消息數(shù)目是否等于消息隊(duì)列的長(zhǎng)度來(lái)判斷步驟(2)中的消息隊(duì)列是否為滿。
6.根據(jù)權(quán)利要求1所述的方法,其特征在于步驟(2)中的取出一條消息放入緩存鏈表是通過(guò)調(diào)用系統(tǒng)的或用戶自己的接收消息函數(shù),以永久等待的方式從發(fā)送者的消息隊(duì)列上接收一條消息,并將該消息插入緩存鏈表中的。
7.根據(jù)權(quán)利要求6所述的方法,其特征在于如果接收到的消息是一個(gè)消息串,則將該消息串的尾部作為消息緩存鏈表的尾部,否則,將該消息作為緩存鏈表的尾部。
8.根據(jù)權(quán)利要求1所述的方法,其特征在于在發(fā)送消息不成功并且消息隊(duì)列不滿時(shí),將發(fā)送者所在的任務(wù)延時(shí)一段時(shí)間后再次發(fā)送消息。
9.根據(jù)以上任何一個(gè)權(quán)利要求所述的方法,其特征在于數(shù)據(jù)結(jié)構(gòu)的組織采用如下方式所有的消息都需要一個(gè)消息控制頭,緊跟著消息控制頭后面的是消息體,在消息控制頭中有一個(gè)指針,指向下一個(gè)消息。
全文摘要
本發(fā)明提出一種在多任務(wù)操作系統(tǒng)中解決任務(wù)死鎖的方法,涉及通信領(lǐng)域。它是基于將可能導(dǎo)致死鎖的有限資源擴(kuò)展為無(wú)限資源的機(jī)制。本發(fā)明通過(guò)在消息控制頭中增加一個(gè)指向下一個(gè)消息的指針來(lái)實(shí)現(xiàn)對(duì)消息的緩存,形成緩存鏈表;通過(guò)發(fā)送者在發(fā)送消息時(shí)查看本身所在的任務(wù)的消息隊(duì)列是否為滿,若滿則取出一條消息放入緩存鏈表的方式來(lái)確保任務(wù)間不會(huì)出現(xiàn)因互發(fā)消息導(dǎo)致死鎖。采用本發(fā)明所述方法,對(duì)于系統(tǒng)中突發(fā)的消息流,可以進(jìn)行暫時(shí)的緩沖,保證在多任務(wù)操作系統(tǒng)中,任務(wù)不會(huì)因?yàn)榛グl(fā)消息而導(dǎo)致死鎖,也不用擔(dān)心消息會(huì)被丟棄而引起系統(tǒng)不穩(wěn)定的現(xiàn)象的發(fā)生,為系統(tǒng)的穩(wěn)定運(yùn)行提供了保障。
文檔編號(hào)G06F9/44GK1713138SQ20041004822
公開(kāi)日2005年12月28日 申請(qǐng)日期2004年6月15日 優(yōu)先權(quán)日2004年6月15日
發(fā)明者鄧紅波, 周元慶, 周海山 申請(qǐng)人:中興通訊股份有限公司