專利名稱:檢測多線程程序中的死鎖的方法和裝置的制作方法
技術(shù)領(lǐng)域:
本發(fā)明一般涉及多線程程序,特別是涉及用于檢測多線程程序中的死鎖的技術(shù)。
背景技術(shù):
死鎖是其中多個進程被禁止取得進展的一種惡性狀況,因為各個進程都在等待某其他進程正在使用的、一個或多個資源。然而,由于死鎖只在涉及例如正在執(zhí)行的線程的交錯或時序的特定條件下才可能發(fā)生,它是難以檢測的。
在死鎖的一簡單示例中,操作系統(tǒng)包含兩個文件,即文件1與文件2。兩個并行運行的進程,即線程1與線程2,都需要文件1與文件2來成功完成。如果線程1打開了文件1且線程2打開了文件2,當(dāng)線程1試圖在關(guān)閉文件1之前打開文件2、而線程2試圖在關(guān)閉文件2之前打開文件1時,可能導(dǎo)致死鎖。這樣,這兩個進程可能永遠等待下去。
有幾位作者通過應(yīng)用關(guān)于要求不同資源的并行運行線程的基本假設(shè),已經(jīng)提供了死鎖的表征,例如,可參見W.W.Collier的“System Deadlocks”(Tech.Rep.TR-00.1756,IBM Systems Development Division,New York,1968)、J.W.Havender的“Avoiding Deadlock in Multitasking Systems”(IBM Syst.J.7,2(1968),pp.74-84)、J.E.Murphy的“Resource Allocationwith Interlock Detection in a Multi-Task System(In Proc.FJCC,AEIPS(1968),vol.33)以及A.Shoshani等人的“Prevention,Detection,andRecovery from System Deadlocks”(In Proceeding of the Fourth AnnualPrinceton Conference on Information Sciences and Systems(Mar.1970))。
關(guān)于并行運行的線程可做出的三個這種基本假設(shè)包括
(1)互斥—線程要求對它們需要的資源擁有排他性控制;(2)等待—線程保持已分配給它們的資源,并必須等待其他需要的資源;以及(3)非搶占—直到將資源用到完成,不能從保持資源的線程強行移除資源。
在JavaTM語言(Sun Microsystems公司)的情境中,上述三個基本假設(shè)滿足,且感興趣的資源是鎖(lock)。
當(dāng)這些基本假設(shè)成立時,可用資源圖對死鎖進行表征,例如可參見W.W.Collier、J.W.Havender、J.E.Murphy和A.Shoshani等。圖被定義為對(N,E),其中N為節(jié)點的集合,E為邊的集合。如果有n個不同的資源,則圖中有n個節(jié)點,每個節(jié)點代表單個資源。每個邊為(v,w)的形式,其中,v∈N,w∈N。如果存在一線程、該線程具有獲得資源v接著又請求資源w的執(zhí)行路徑,則邊(v,w)從節(jié)點v延伸到節(jié)點w。圖中的路徑是邊的集合{(vi,vi+1)|i=1,...n},其中,n≥1。循環(huán)是這樣的路徑,其中,v1,......,vn全部不同,且vn+1=v1。
假設(shè)線程沒有請求其已經(jīng)獲得的資源,如果發(fā)生死鎖,則資源圖包含至少一個循環(huán)。在例如JavaTM等編程語言的情境中,圖的使用可被稱為鎖循環(huán)策略,這是因為對于鎖的獲取和請求循環(huán)的搜索。
因此,希望在不執(zhí)行多線程程序代碼的情況下通過多線程程序的源代碼和目標(biāo)代碼自動判斷是否將發(fā)生死鎖。
發(fā)明內(nèi)容
在例如JavaTM等多線程語言中,為了正確地發(fā)揮程序功能,死鎖是應(yīng)當(dāng)避免的嚴(yán)重狀況。在JavaTM字節(jié)碼中檢測死鎖的、本發(fā)明的實施例是自動的,且不需要字節(jié)碼的任何注釋。死鎖的存在被準(zhǔn)確地報告,且用戶可檢查輸出,以便確定是否需要修改代碼。因此,根據(jù)本發(fā)明的實施例,可使用靜態(tài)分析技術(shù)。
例如,在本發(fā)明的一個方面中,提供了一種檢測多線程程序中的死鎖的方法。構(gòu)建了調(diào)用圖,其具有對應(yīng)于以多線程程序代碼編寫的一個或多個函數(shù)的單個根和多個節(jié)點。根據(jù)在調(diào)用圖的各個節(jié)點上起作用的一個或多個資源集合計算出資源圖。判斷資源圖中兩個或兩個以上的節(jié)點之間是否存在循環(huán)。循環(huán)是多線程程序中死鎖的指示。
另外,可通過按照在調(diào)用圖各節(jié)點上起作用的資源集合構(gòu)建節(jié)點和邊的集合,來構(gòu)建資源圖。可通過后處理對資源圖的定義進行精練,以生成額外的邊。最后,可向用戶報告任何循環(huán)以及所關(guān)聯(lián)的路徑信息。
本發(fā)明的方法包括既在過程間又在過程內(nèi)的層面進行詳細(xì)的報告,從而允許清楚地識別資源爭用位置。該方法是普遍的,因為它通過涉及圖而不涉及編程語言細(xì)節(jié)的、對程序的抽象描述,而對資源循環(huán)策略(resourcecycle strategy)進行工作。因此,本發(fā)明的實施例可應(yīng)用于實現(xiàn)監(jiān)視器(monitor)的任何語言,并可被伸縮以解決大型問題。
通過結(jié)合附圖閱讀下面對本發(fā)明的示例性實施例的詳細(xì)介紹,可了解本發(fā)明的這些以及其他目標(biāo)、特征和優(yōu)點。
圖1為示出了根據(jù)本發(fā)明一實施例的死鎖檢測方法的流程圖;圖2為示出了根據(jù)本發(fā)明一實施例的鎖圖計算方法的流程圖;圖3為根據(jù)本發(fā)明一實施例的鎖集合構(gòu)建方法;圖4為用于一示例的JavaTM代碼,該示例用于說明本發(fā)明的實施例;圖5為用于該示例的索引、程序計數(shù)器和源行號的表,訪示例用于說明本發(fā)明的實施例;圖6為用于該示例的調(diào)用圖的一部分,該示例用于說明本發(fā)明的實施例;圖7為用于該示例的鎖圖,該示例用于說明本發(fā)明的實施例;圖8為為該示例所產(chǎn)生的輸出,該示例用于說明本發(fā)明的實施例;以及圖9為示出了計算系統(tǒng)的示例性硬件實現(xiàn)的框圖,根據(jù)本發(fā)明的一實施例,根據(jù)該計算系統(tǒng)可實現(xiàn)本發(fā)明一個或多個組件/方法。
具體實施例方式
如下面將詳細(xì)示出的那樣,本發(fā)明介紹了用于檢測多線程程序中的死鎖的技術(shù)。可以為任何實現(xiàn)了監(jiān)視器的多線程程序?qū)崿F(xiàn)本發(fā)明的實施例,然而,出于說明目的,這里它們被描述為應(yīng)用于JavaTM程序。
既可以對源代碼又可以對字節(jié)碼利用本發(fā)明的實施例。在前一種情況下,對源代碼進行編譯,并將該方法應(yīng)用于包含字節(jié)碼的JavaTM檔案(jar)文件。在后一種情況下,即使源代碼不可用—這種情況可能經(jīng)常發(fā)生,也可應(yīng)用該方法。這些實施例是自動的,且不需要代碼注釋。將jar文件與某些配置數(shù)據(jù)一起輸入到系統(tǒng),并且輸出為包括可能的死鎖的概要的報告。
JavaTM語言利用了監(jiān)視器,監(jiān)視器通過確保代碼體一次只被一個線程執(zhí)行,來保護代碼體。這是通過使用與每一JavaTM對象隱式地關(guān)聯(lián)的鎖來實現(xiàn)的。因此,如同上面所介紹的那樣以及根據(jù)本發(fā)明實施例,資源圖被稱為鎖圖。為了開始構(gòu)建鎖圖,提供一JavaTM程序,該程序由幾組字節(jié)碼組成。
最初參照圖1,一流程圖示出了根據(jù)本發(fā)明實施例的高級死鎖檢測方法。該方法開始于方框102,在該方框中,構(gòu)建具有單個根或相關(guān)的入口點的調(diào)用圖。在方框104中,通過考慮從根到源—在此資源被獲得或被請求—的所有可能的執(zhí)行路徑,計算出鎖圖。出于報告目的,保留路徑信息。在方框106中,判斷結(jié)果得到的鎖圖是否具有任何循環(huán)。在方框108中,向用戶報告任何循環(huán)以及相關(guān)聯(lián)的路徑信息。
在本發(fā)明的優(yōu)選實施例中,利用了JavaTM字節(jié)碼分析(JaBA)系統(tǒng),該系統(tǒng)使用靜態(tài)分析技術(shù)來為以JavaTM字節(jié)碼編寫的方法或函數(shù)構(gòu)建調(diào)用圖。JaBA還生成關(guān)于變量和鎖的值的信息。該系統(tǒng)是對流敏感的,因為,每個方法的控制流圖考慮了每個基本塊中指令的執(zhí)行順序,并考慮到局部變量取消和對象引用的類型轉(zhuǎn)換(casting)。該系統(tǒng)還是對上下文敏感的,因為調(diào)用圖中的每個節(jié)點由其調(diào)用上下文—即方法、一組可能的接收者類型以及可能的參數(shù)類型—唯一地標(biāo)識。
調(diào)用圖中的每個節(jié)點代表了一方法和一特定的上下文,并包含該方法的控制流圖的基本塊以及訪問和釋放鎖的位置。調(diào)用圖還具有過程間的邊(A,B),其代表從方法A的內(nèi)部對方法B的調(diào)用。該邊從A中的指令—在此發(fā)生該調(diào)用—延伸到B的控制流圖的初始頂點。本發(fā)明的調(diào)用圖允許雙向遍歷,即使圖中的邊是單向的。因此,從調(diào)用圖中的任何節(jié)點n,可找到其前面的節(jié)點的集合和后面的節(jié)點的集合。
除調(diào)用圖外,執(zhí)行精度達到分配點(allocation site)的層面的數(shù)據(jù)流分析,其中,每個分配被唯一標(biāo)識。由調(diào)用圖建模的JavaTM程序中的對象的數(shù)量總是有限的。對象代碼中存在有限數(shù)量的調(diào)用,數(shù)組和其他匯集(collection)中的元素被建模為單個元素。JaBA還產(chǎn)生這樣的文件,該文件指示所有被檢查的類以及它們的層級關(guān)系。
如上所述,鎖圖由(N,E)給出。N的每個元素是對應(yīng)于JavaTM程序中的對象的一組鎖。令v∈N以及w={w1,w2,...,wm}∈N,則如果程序中存在這樣的執(zhí)行路徑,對于該執(zhí)行路徑線程已經(jīng)獲得了至少鎖集合v并請求集合w,那么, (v,w1)∈E,i=1,......,m。
如果JavaTM程序有n個鎖,則理論上存在2n個節(jié)點,對應(yīng)于n個元素的所有可能的子集。然而,可以忽略孤立的節(jié)點,即沒有邊離開或進入的節(jié)點。在實踐中,該圖被遞增地構(gòu)建,隨著鎖集合和邊在程序路徑的遍歷中出現(xiàn)而添加鎖集合和邊,且節(jié)點數(shù)量遠遠少于理論最大值。
現(xiàn)參照圖2,一流程圖示出了根據(jù)本發(fā)明實施例的鎖圖計算方法。這可以看作是圖1中的方框104的詳細(xì)描述。鎖圖的構(gòu)建在兩個階段中進行。在方框202中,結(jié)合例如G.B.Leeman等人在“Detecting UnwantedSynchronization in Java Programs”(Tech.Rep.RC 22552,IBM ThomasJ.Watson Research Center,Yorktown Heights,New York,Sept.2002)中介紹的鎖集合計算算法,構(gòu)建節(jié)點和邊的集合。如同下面將詳細(xì)介紹的那樣,鎖圖計算利用在調(diào)用圖的每個節(jié)點上起作用以及在每個基本塊中的、計算得到的鎖集合來構(gòu)建鎖圖中的節(jié)點和邊的集合。在方框204中,被稱為后處理的第二步驟對圖的定義進行精練。
鎖被定義為對(o,c),其中,o為JavaTM程序中的對象,c,即計數(shù)器,是界限為固定常數(shù)Ω的正整數(shù)。鎖集合是鎖的匯集,其中,所有的對象o是不同的。在JavaTM程序的調(diào)用圖模型中,JavaTM對象的總數(shù)量是有限的。因此,對于該程序,可能的不同鎖集合的數(shù)量是有限的。
給定鎖集合m,加法(+)—其對應(yīng)于monitorenter—被定義如下●如果對于某些c,(o,c)∈m,則用(o,min(c+1,Ω))代替m中的(o,c);●否則,將(o,1)添加到m。
結(jié)果得到的集合為m+o。
對于集合m與鎖(o,c)的并集(∪),●如果o沒有出現(xiàn)在m的任何鎖對象中,則將(o,c)添加到m;●如果(o,d)∈m,d<c,則在m中用(o,c)替代(o,d);●如果(o,d)∈m,d=c,則m保持不變。
結(jié)果得到的集合為m∪(o,c)。
通過為每個o∈m2計算m1(+或∪,將+和∪擴展到兩個集合m1和m2上的操作。
實際上,計數(shù)器的使用很少在字節(jié)碼中出現(xiàn)。因此,可設(shè)置Ω=1的條件。
并集操作表示這樣的事實,即調(diào)用圖后繼節(jié)點繼承了其前驅(qū)的鎖集合如果節(jié)點i有鎖集合mi,i=1,2,且節(jié)點2為節(jié)點1的后繼,那么在計算中的某點上,將用m1∪m2來代替m2。
現(xiàn)參照圖3,提供了根據(jù)本發(fā)明實施例的鎖集合構(gòu)建方法。這可被看作圖2中的方框202的詳細(xì)描述。在該定點算法中,節(jié)點和邊指調(diào)用圖的部分。為JavaTM程序的每個線程執(zhí)行該方法;開始節(jié)點是線程的start()方法,且首先用所有從其start()節(jié)點可到達的節(jié)點形成線程閉包集合(closure set)。
該方法最初的四個步驟為初始化。步驟1初始化空的鎖集合和空的圖。步驟2初始化用于具有同步的塊的節(jié)點的所有結(jié)構(gòu),所述同步的塊記錄了哪些基本塊包含monitorenters和monitorexits。步驟3基于同步的方法初始化所有鎖集合,具體而言,基于同步的方法為節(jié)點和邊計算鎖集合的初始值。步驟4將開始值放入隊列?!翱铡钡逆i圖實際上有表示空鎖集合的一個節(jié)點(節(jié)點0)。
主循環(huán)在該方法的步驟5至15中提供。在步驟7中計算當(dāng)前鎖集合,如果必要,更新鎖圖。無論何時請求了新的鎖,可添加新的頂點和邊。步驟8執(zhí)行過程內(nèi)分析,以便確定基本塊和邊的鎖集合,參見例如G.B.Leeman等。再一次地,這一步驟可能使更新鎖圖成為必要。最后,步驟9至15執(zhí)行過程間分析,以便為離開當(dāng)前節(jié)點的各邊計算鎖集合,步驟10。如果后繼節(jié)點的鎖集合被改變,步驟11-14,則將后繼節(jié)點添加到當(dāng)前路徑,并將它們放入隊列,步驟15。出于報告目的,路徑由鎖圖保持。
如圖2中的方框204中描述的通過后處理對圖的定義進行精練涉及對當(dāng)前頂點集合進行檢查,以生成額外的邊。應(yīng)記得,第一階段在每個線程上運行,從而可能產(chǎn)生新的鎖圖節(jié)點和邊。如果線程t產(chǎn)生邊(p(t),s(t)),那么,某些執(zhí)行路徑獲得至少前驅(qū)集合p(t)中的鎖,并請求后繼集合s(t)中的鎖。類似地,假設(shè)第二線程t′產(chǎn)生邊(p(t′),s(t′))。條件p(t)∩p(t′)≠φ表示不會發(fā)生的情況,因為JavaTM線程和鎖滿足互斥屬性。然而,p(t)∩p(t′)=φ,那么可創(chuàng)建可能感興趣的額外邊。也就是說,對于p(t)中的每個鎖m,產(chǎn)生新的節(jié)點{m}(除非該節(jié)點已經(jīng)存在)以及從{m}到s(t)的邊(除非這一邊已經(jīng)存在);為p(t′)進行類似的操作。因此,方框204包括線程的成對檢查以及經(jīng)由該過程的額外節(jié)點和邊的創(chuàng)建。
經(jīng)典的哲學(xué)家就餐問題可用于描述本發(fā)明的實施例,例如參見A.Silberschatz等人的“Operating System Concepts”(sixth ed.,JohnWiley & Sons,Inc.New York,New York,2002)?,F(xiàn)參照圖4,示出了用于經(jīng)典的哲學(xué)家就餐問題的JavaTM代碼,該問題有四位哲學(xué)家和五支筷子,其中,哲學(xué)家需要兩支筷子(資源)來進餐,最終導(dǎo)致死鎖。
圖4中的JavaTM代碼的行44-49創(chuàng)建了五個哲學(xué)家對象,三個參數(shù)分別表示哲學(xué)家名字、他左邊的筷子以及他右邊的筷子。筷子用行2-6中的字符串表示。每位哲學(xué)家也是一個線程(行1),線程在行50-54開始,這使得運行方法(行15-39)被執(zhí)行。該方法對每位哲學(xué)家的行為建模他坐在分配給他的兩支筷子之間(行16),并然后進入思考-拿起-進餐的循環(huán)(行18-34),其中,每個動作占用隨機大小的時間。在該循環(huán)中,他思考(行19-20),拿起他左邊的筷子(行21-24),拿起他右邊的筷子(行25-28),并進餐(行29-33)。JavaTM同步塊反映了筷子的互斥、等待以及非搶占屬性。當(dāng)運行此程序時,迅速達到死鎖。
根據(jù)本發(fā)明的實施例,通過JaBA,對象用以下形式的列表表示index type classmethodprogramCounter surceLine例如,筷子1對象被表示為14 NewSite PhilosopherPhilosopher.main([java.lang.String])PC 0 SL 2索引是分配給每一對象的唯一號碼。如果源代碼不可用,源行條目為-1。就餐哲學(xué)家問題的重要對象全都具有同樣的類型、類、類加載器以及方法。索引、程序計數(shù)器和源行號碼在圖5中的表中示出。另外,就餐哲學(xué)家示例的一部分調(diào)用圖在圖6中示出。所提供的示例具有11個鎖(5位哲學(xué)家,5支筷子和Math鎖),但存在遠遠少于211個的節(jié)點,具體為22個節(jié)點和40個邊。
可以為就餐哲學(xué)家示例跟蹤第一階段的進展。存在五個開始節(jié)點(行50-54),其中,應(yīng)用圖3中的方法。注意,start()實際上是這樣的形式public synchronized nativejava.lang.Thread.start因此,根據(jù)本發(fā)明實施例,對于每個開始節(jié)點,圖3中的步驟7引起鎖圖中的節(jié)點16、1、19、7和12的創(chuàng)建,如圖7中所示。這些整數(shù)對應(yīng)于圖5的表中的索引。另外,形成了五個邊(0,1),(0,7),(0,12),(0,16),(0,19)這意味著,線程獲得至少沒有鎖(節(jié)點0)并請求單個鎖,來運行開始方法。
start()的后繼是run方法。圖3中的步驟8執(zhí)行的圖4中行22的處理引起圖7的鎖圖中新的鎖圖節(jié)點14、2、4、8和10的創(chuàng)建,它們對應(yīng)于圖5的表中的五個筷子對象。還存在新的邊(16,14),(1,2),(19,4),(7,8),(12,10),特別是從行45(16,14)表示start()獲得至少frege鎖(16)并接著在行22請求chopstick1鎖(14)。類似地,當(dāng)分析行26時,創(chuàng)建新的鎖集合和JavaTM鎖圖節(jié)點17={16,14},3={1,2},20={19,4},9={7,8},13={12,10}接著創(chuàng)立邊(17,2),(3,4),(20,8),(9,10),(13,14),
例如,在獲取至少frege和chopstick1鎖{{16,14},到17的集合}之后,請求chopstick2(2),導(dǎo)致產(chǎn)生邊(17,2)。
由于各種內(nèi)建方法的簽名,經(jīng)常產(chǎn)生意料之外的節(jié)點。在我們的示例中,random方法(行41)調(diào)用initRNG,其具有簽名private static synchronizedjava.lang.Math.initRNG()V}因此,存在新的鎖,該鎖由Math類的類對象組成,并生成具有三個元素(哲學(xué)家,筷子和Math鎖)的鎖集合,以及額外的節(jié)點和邊。然而,由于它們不使人感興趣,未對它們進行討論。
圖2中的方框204不創(chuàng)建任何新的頂點。然而,哲學(xué)家frege線程產(chǎn)生邊(17,2),哲學(xué)家hegel線程產(chǎn)生邊(3,4)。集合17和3是不相交的,故方框402提出新的邊({16},2)、({14},2)、({1},4)和({2},4),這在我們的標(biāo)記法中與(16,2)、(14,2)、(1,4)和(2,4)是一樣的。邊(1,4)已經(jīng)存在,但其他三個是新的。不難判斷,哲學(xué)家kant和mill產(chǎn)生新的邊(4,8)、(7,10)、(8,10),哲學(xué)家plato和任何其他哲學(xué)家對象產(chǎn)生兩個新的邊(10,14)和(12,14)。從具有三個元素的鎖集合中還產(chǎn)生了更多的邊,這些在本說明性示例中沒有處理。
在就餐哲學(xué)家示例中,正好發(fā)現(xiàn)一個循環(huán)2→4→8→10→14→2在圖8中,提供了根據(jù)本發(fā)明實施例為就餐哲學(xué)家示例所產(chǎn)生的輸出的示例。
當(dāng)JavaTM鎖圖具有循環(huán)時,對信息進行報告,且用戶可使用該信息判斷是否存在死鎖。由于靜態(tài)分析經(jīng)常產(chǎn)生假的肯定,必須檢查每個輸出匯集。當(dāng)圖中沒有循環(huán)時,該狀況是沒有死鎖的強烈證據(jù)。用戶能夠觀察所分析的線程,以便查看死鎖不存在。通常,靜態(tài)分析不能遍歷所有可能的程序執(zhí)行,且在JavaTM中,例如反射(reflection)等動態(tài)特征使該問題更加惡化。
D.Lea在“Concurrent Programming in Java Design Principles andPatterns”(Addison-Wesley,Reading,MA,1997)中提供了兩路(two-way)死鎖的簡單示例。也可參見C.Demartini等人的“A Deadlock DetectionTool for Concurrent java Programs”(Software-Practice and Experience29,7,June 1999,pp.577-603)。然而,這些參考文獻提供了相對復(fù)雜的分析。本發(fā)明的實施例通過生成僅具有7個節(jié)點、10個邊和1個循環(huán)的鎖圖,提供了特別簡單的分析。正好兩個節(jié)點v和w有這樣的屬性(v,w)和(w,v)均為邊,從而產(chǎn)生循環(huán)和死鎖。盡管本發(fā)明的實施例已在分析JavaTM代碼的情境中示出,它們可應(yīng)用于支持監(jiān)視器的任何語言。
現(xiàn)參照圖9,框圖示出了一計算系統(tǒng)的示例性硬件實現(xiàn),根據(jù)本發(fā)明的一實施例的,可根據(jù)該計算系統(tǒng)實現(xiàn)本發(fā)明的一個或多個組件/方法(例如在圖1-8的情境中介紹的組件/方法)。
如圖所示,計算機系統(tǒng)可根據(jù)經(jīng)由計算機總線918或其他連接裝置耦合的處理器910、存儲器912、I/O設(shè)備914以及網(wǎng)絡(luò)接口916實現(xiàn)。
應(yīng)當(dāng)理解,這里所用的術(shù)語“處理器”旨在包括任何處理裝置,比如,舉例來說,包括CPU(中央處理單元)和/或其他處理電路的處理裝置。還應(yīng)理解,術(shù)語“處理器”可以指一個以上的處理裝置,且與一處理裝置相關(guān)聯(lián)的各元素可以與其他處理裝置共享。
這里所用的術(shù)語“存儲器”旨在包括與處理器或CPU相關(guān)聯(lián)的存儲器,比如,舉例來說,RAM、ROM、固定存儲設(shè)備(例如硬盤驅(qū)動器)、可拆裝存儲設(shè)備(例如磁盤)、閃速存儲器等。
另外,這里所用的短語“輸入/輸出設(shè)備”或“I/O設(shè)備”包括例如用于向處理單元輸入數(shù)據(jù)的一個或多個輸入設(shè)備(例如鍵盤、鼠標(biāo)、掃描儀、攝像機等),和/或用于呈現(xiàn)與處理單元相關(guān)聯(lián)的結(jié)果的一個或多個輸出設(shè)備(例如揚聲器、顯示器、打印機等)。
另外,這里所用的“網(wǎng)絡(luò)接口”旨在包括例如一個或多個收發(fā)器,所述收發(fā)器允許計算機系統(tǒng)經(jīng)由合適的通信協(xié)議與其他的計算機系統(tǒng)通信。
包括用于執(zhí)行這里所介紹的方法的指令或代碼的軟件組件可存儲在一個或多個關(guān)聯(lián)的存儲設(shè)備(例如ROM、固定存儲器或可拆裝存儲器)中,且當(dāng)準(zhǔn)備使用時,部分或全部裝載(例如裝載到RAM)并由CPU執(zhí)行。
這里介紹的本發(fā)明實施例提供了一種自動方法,該方法用于檢測支持監(jiān)視器概念以獲得同步的語言中的死鎖。它既為源代碼也為字節(jié)碼工作,因為前者可被編譯為后者,而后者被分析。不需要代碼注釋。
盡管這里參照附圖介紹了本發(fā)明的說明性實施例,可以理解,本發(fā)明不限于這些具體實施例,并且在不脫離本發(fā)明的范圍或精神的情況下,本領(lǐng)域技術(shù)人員可進行各種各樣的其他改變和更改。
權(quán)利要求
1.一種檢測多線程程序中的死鎖的方法,該方法包括以下步驟構(gòu)建調(diào)用圖,所述調(diào)用圖具有對應(yīng)于以所述多線程程序的代碼編寫的、一個或多個函數(shù)的一個根以及多個節(jié)點;根據(jù)在所述調(diào)用圖的每個節(jié)點上起作用的、一個或多個資源集合,計算資源圖;以及判斷在所述資源圖的兩個或更多個節(jié)點之間是否存在循環(huán),其中,循環(huán)是所述多線程程序中死鎖的指示。
2.根據(jù)權(quán)利要求1的方法,其中,所述多線程程序包括JavaTM程序。
3.根據(jù)權(quán)利要求1的方法,其中,在所述構(gòu)建調(diào)用圖的步驟中,每個節(jié)點包括以所述多線程程序的代碼編寫的函數(shù)的控制流圖的基本塊,以及資源被訪問和釋放的位置。
4.根據(jù)權(quán)利要求1的方法,其中,在所述構(gòu)建調(diào)用圖的步驟中,每個連接兩個節(jié)點的邊對應(yīng)于從以所述多線程程序的代碼編寫的一函數(shù)內(nèi)部對以所述多線程程序的代碼編寫的另一函數(shù)的調(diào)用。
5.根據(jù)權(quán)利要求1的方法,其中,在所述構(gòu)建調(diào)用圖的步驟中,所述調(diào)用圖允許節(jié)點之間的雙向遍歷,以便確定前驅(qū)節(jié)點和后繼節(jié)點的集合。
6.根據(jù)權(quán)利要求1的方法,其中,所述構(gòu)建調(diào)用圖的步驟包括執(zhí)行數(shù)據(jù)流分析的步驟。
7.根據(jù)權(quán)利要求1的方法,其中,在所述構(gòu)建調(diào)用圖的步驟中,所述調(diào)用圖中的每個節(jié)點可由一調(diào)用上下文標(biāo)識。
8.根據(jù)權(quán)利要求7的方法,其中,所述調(diào)用上下文包括目標(biāo)函數(shù)、一組可能的接收者類型以及參數(shù)類型中的至少一個。
9.根據(jù)權(quán)利要求1的方法,其中,在所述計算資源圖的步驟中,資源包括對象和計數(shù)器,且資源集合包括具有不同對象的資源。
10.根據(jù)權(quán)利要求1的方法,其中,所述計算資源圖的步驟包括以下步驟根據(jù)在所述調(diào)用圖的每個節(jié)點上起作用的資源集合,構(gòu)建節(jié)點和邊的集合;以及通過后處理,對所述資源圖的定義進行精練。
11.根據(jù)權(quán)利要求10的方法,其中,所述構(gòu)建節(jié)點和邊的集合的步驟包括以下步驟由所述調(diào)用圖計算第一資源集合;隨著資源被請求,添加邊;為離開所述第一資源集合的節(jié)點的每個邊計算資源集合;在每一步驟后根據(jù)需要更新所述資源圖;以及為每一新創(chuàng)建的資源集合重復(fù)所述計算第一資源集合、添加邊、計算資源集合以及更新所述資源圖的步驟。
12.根據(jù)權(quán)利要求10的方法,其中,對所述鎖圖的定義進行精練的所述步驟包括檢查當(dāng)前的頂點集合以生成額外的邊的步驟。
13.根據(jù)權(quán)利要求1的方法,還包括報告任何循環(huán)以及所關(guān)聯(lián)的路徑信息的步驟。
14.一種用于檢測多線程程序中的死鎖的裝置,包括存儲器;以及至少一個處理器,該處理器耦合到所述存儲器并可運行以執(zhí)行以下操作(i)構(gòu)建調(diào)用圖,所述調(diào)用圖具有對應(yīng)于以所述多線程程序的代碼編寫的、一個或多個函數(shù)的一個根以及多個節(jié)點;(ii)根據(jù)在所述調(diào)用圖的每個節(jié)點上起作用的、一個或多個資源集合,計算資源圖;以及(iii)判斷在所述資源圖的兩個或更多個節(jié)點之間是否存在循環(huán),其中,循環(huán)是所述多線程程序中死鎖的指示。
15.根據(jù)權(quán)利要求14的裝置,其中,所述多線程程序包括JavaTM程序。
16.根據(jù)權(quán)利要求14的裝置,其中,在所述構(gòu)建調(diào)用圖的操作中,每個節(jié)點包括以所述多線程程序的代碼編寫的函數(shù)的控制流圖的基本塊,以及資源被訪問和釋放的位置。
17.根據(jù)權(quán)利要求14的裝置,其中,在所述構(gòu)建調(diào)用圖的操作中,每個連接兩個節(jié)點的邊對應(yīng)于從以所述多線程程序的代碼編寫的一函數(shù)內(nèi)部對以所述多線程程序的代碼編寫的另一函數(shù)的調(diào)用。
18.根據(jù)權(quán)利要求14的裝置,其中,在所述構(gòu)建調(diào)用圖的操作中,所述調(diào)用圖允許節(jié)點之間的雙向遍歷,以便確定前驅(qū)節(jié)點和后繼節(jié)點的集合。
19.根據(jù)權(quán)利要求14的裝置,其中,所述構(gòu)建調(diào)用圖的操作包括執(zhí)行數(shù)據(jù)流分析的步驟。
20.根據(jù)權(quán)利要求14的裝置,其中,在所述構(gòu)建調(diào)用圖的操作中,所述調(diào)用圖中的每個節(jié)點可用調(diào)用上下文標(biāo)識。
21.根據(jù)權(quán)利要求20的方法,其中,所述調(diào)用上下文包括目標(biāo)函數(shù)、一組可能的接收者類型以及參數(shù)類型中的至少一個。
22.根據(jù)權(quán)利要求14的裝置,其中,在所述計算資源圖的操作中,資源包括對象和計數(shù)器,且資源集合包括具有不同對象的資源。
23.根據(jù)權(quán)利要求14的裝置,其中,所述計算資源圖的操作包括以下步驟根據(jù)在所述調(diào)用圖的每個節(jié)點上起作用的所述資源集合,構(gòu)建節(jié)點和邊的集合;以及通過后處理,對所述資源圖的定義進行精練。
24.根據(jù)權(quán)利要求23的裝置,其中,所述構(gòu)建節(jié)點和邊的集合的步驟包括以下步驟由所述調(diào)用圖計算第一資源集合;隨著資源被請求,添加邊;為離開所述第一資源集合的節(jié)點的每個邊計算資源集合;在每個步驟后根據(jù)需要更新所述資源圖;以及為每一新創(chuàng)建的資源集合重復(fù)所述計算第一資源集合、添加邊、計算資源集合以及更新所述資源圖的步驟。
25.根據(jù)權(quán)利要求24的裝置,其中,對所述鎖圖的定義進行精練的所述步驟包括對當(dāng)前的頂點集合進行檢查以產(chǎn)生額外的邊的步驟。
26.根據(jù)權(quán)利要求14的裝置,還包括報告任何循環(huán)以及所關(guān)聯(lián)的路徑信息的操作。
27.一種用于檢測多線程程序中的死鎖的制造物品,該制造物品包括機器可讀的介質(zhì),該機器可讀的介質(zhì)包含有一個或多個程序,所述程序在被執(zhí)行時實現(xiàn)以下步驟構(gòu)建調(diào)用圖,所述調(diào)用圖具有對應(yīng)于以所述多線程程序的代碼編寫的、一個或多個函數(shù)的一個根以及多個節(jié)點;根據(jù)在所述調(diào)用圖的每個節(jié)點上起作用的一個或多個資源集合,計算資源圖;以及判斷在所述資源圖的兩個或更多個節(jié)點之間是否存在循環(huán),其中,循環(huán)是所述多線程程序中死鎖的指示。
全文摘要
本發(fā)明提供了一種檢測多線程程序中的死鎖的方法。構(gòu)建調(diào)用圖,該調(diào)用圖具有對應(yīng)于以多線程程序的代碼編寫的、一個或多個函數(shù)的一個根和多個節(jié)點。根據(jù)在調(diào)用圖的每個節(jié)點上起作用的、一個或多個資源集合,計算資源圖。判斷在資源圖的兩個或更多個節(jié)點之間是否存在循環(huán)。循環(huán)是多線程程序中死鎖的指示。
文檔編號G06F9/46GK1987796SQ20061014707
公開日2007年6月27日 申請日期2006年11月14日 優(yōu)先權(quán)日2005年12月22日
發(fā)明者G·小萊曼 申請人:國際商業(yè)機器公司