⑴ 求一個在C語言環境下進行死鎖檢測的程序
#include<stdio.h>
#include<iostream.h>
#include<string.h>
const int MAXQUEUE=100; //定義表的最大行數
typedef struct node{
int resource;
int process;
}cell;
cell occupy[MAXQUEUE];
int occupy_quantity;
cell wait[MAXQUEUE];
int wait_quantity;
//初始化函數
void initial()
{
int i;
for(i=0;i<MAXQUEUE;i++){
occupy.process=-1;
occupy.resource=-1;
wait.process=-1;
wait.resource=-1;
}
occupy_quantity=0;
wait_quantity=0;
}
//讀數據文件
int readData()
{
FILE *fp;
char fname[20];
int i;
cout<<"請輸入資源分配表文件的文件名:"<<endl;
strcpy(fname,"10trouble1.txt");
//cin>>fname;
if((fp=fopen(fname,"r"))==NULL){
cout<<"錯誤,文件打不開,請檢查文件名:)"<<endl;
return 0;
}
else{
while(!feof(fp)){
fscanf(fp,"%d %d",&occupy[occupy_quantity].resource,&occupy[occupy_quantity].process);
occupy_quantity++;
}
}
cout<<"請輸入進程等待表文件的文件名:"<<endl;
strcpy(fname,"10trouble2.txt");
//cin>>fname;
if((fp=fopen(fname,"r"))==NULL){
cout<<"錯誤,文件打不開,請檢查文件名:)"<<endl;
return 0;
}
else{
while(!feof(fp)){
fscanf(fp,"%d %d",&wait[wait_quantity].process,&wait[wait_quantity].resource);
wait_quantity++;
}
}
//輸出所讀入的數據
cout<<endl<<endl<<"輸出所讀入的數據"<<endl;
cout<<"━━━━━━━━━━━━━━━━━━━━━━━"<<endl;
cout<<"資源分配表"<<endl;
cout<<"資源編號 進程編號"<<endl;
for(i=0;i<occupy_quantity;i++){
cout<<" "<<occupy.resource<<" "<<occupy.process<<endl;
}
cout<<"———————————————————————"<<endl;
cout<<"進程等待表"<<endl;
cout<<"進程編號 資源編號"<<endl;
for(i=0;i<wait_quantity;i++){
cout<<" "<<wait.resource<<" "<<wait.process<<endl;
}
return 1;
}
//檢測
void check()
{
int table[MAXQUEUE][MAXQUEUE];
int table1[MAXQUEUE][MAXQUEUE];
int i,j,k;
int flag,t,p;
int max_process;
//初始化表格
for(i=0;i<MAXQUEUE;i++){
for(j=0;j<MAXQUEUE;j++){
table[j]=0;
table1[j]=0;
}
}
//先找到進程最大編號
max_process=-1;
for(i=0;i<occupy_quantity;i++){
if(occupy.process>max_process){
max_process=occupy.process;
}
}
for(i=0;i<wait_quantity;i++){
if(wait.process>max_process){
max_process=wait.process;
}
}
for(i=0;i<wait_quantity;i++){
for(j=0;j<occupy_quantity;j++){
if(wait.resource==occupy[j].resource){
table[wait.process][occupy[j].process]=1;
table1[wait.process][occupy[j].process]=1;
}
}
}
cout<<"初始等待佔用表:"<<endl;
for(i=0;i<max_process+1;i++){
for(j=0;j<max_process+1;j++){
cout<<table[j]<<" ";
}
cout<<endl;
}
cout<<endl;
for(i=0;i<max_process+1;i++){
for(j=0;j<max_process+1;j++){
for(k=0;k<max_process+1;k++){
table[j]=table[j]||(table[k]&&table[k][j]);
}
}
}
cout<<"檢測後的等待佔用表:"<<endl;
for(i=0;i<max_process+1;i++){
for(j=0;j<max_process+1;j++){
cout<<table[j]<<" ";
}
cout<<endl;
}
flag=-1;
for(i=0;i<max_process+1;i++){
if(table==1){
flag=i;
break;
}
}
cout<<endl<<endl<<"檢測結果"<<endl;
cout<<"———————————————————"<<endl;
if(flag!=-1){
cout<<"存在死鎖"<<endl;
cout<<"進程循環等待隊列:";
p=flag; //存在進程循環等待隊列的那一進程
//進程循環等待隊列中的所有進程是table表中的這一行是1的進程,只是順序要再確定
t=1;
while(t){
cout<<p<<" ";
for(j=0;j<max_process+1;j++){
if(table1[p][j]==1){
if(table[j][flag]==1){
p=j;
break;
}
}
}
if(p==flag)t=0;
}
cout<<flag<<endl;
}
else{
cout<<"不存在死鎖"<<endl;
}
}
⑵ 處理死鎖的方法
預防死鎖。這是一種較簡單和直觀的預先預防方法。該方法是通過設置某些限制條件,去破壞產生死鎖的四個必要條件中的一個或幾個來預防產生死鎖。預防死鎖是一種易實現的方法,已被廣泛使用。
避免死鎖。同樣是屬於事先預防策略,但它並不是事先採取各種限制措施,去破壞產生死鎖的四個必要條件,而是在資源的動態分配過程中,用某種方法防止系統進入不安全狀態,從而可以避免發生死鎖。
檢測死鎖。這種方法無須事先採取任何限性制措施,允許進程在運行過程中發生死鎖。但可通過檢測機構及時地檢測出死鎖的發生,然後採取適當的措施,把進程從死鎖中解脫出來。
解除死鎖。當檢測到系統中已發生死鎖時,就採取相應的措施,把進程從死鎖中解脫出來。常用的方法是撤消一些進程,回收它們的資源,將資源分配給已處於阻塞狀態的進程,使其能繼續運行。
⑶ 怎麼解決死鎖現象
產生死鎖的原因:一是系統提供的資源數量有限,不能滿足每個進程的使用;二是多道程序運行時,進程推進順序不合理。
產生死鎖的必要條件是:1、互斥條件;2、不可剝奪條件(不可搶占);3、部分分配;4、循環等待。
根據產生死鎖的四個必要條件,只要使其中之一不能成立,死鎖就不會出現。為此,可以採取下列三種預防措施:
1、採用資源靜態分配策略,破壞"部分分配"條件;
2、允許進程剝奪使用其他進程佔有的資源,從而破壞"不可剝奪"條件;
3、採用資源有序分配法,破壞"環路"條件。
死鎖的避免不嚴格地限制死鎖的必要條件的存在,而是系統在系統運行過程中小心地避免死鎖的最終發生。最著名的死鎖避免演算法是銀行家演算法。死鎖避免演算法需要很大的系統開銷。
解決死鎖的另一條途徑是死鎖檢測方法,這種方法對資源的分配不加限制,即允許死鎖的發生。但系統定時地運行一個"死鎖檢測"程序,判斷系統是否已發生死鎖,若檢測到死鎖發生則設法加以解除。
解除死鎖常常採用下面兩種方法:1、資源剝奪法;2、撤消進程法
⑷ 在linux中用C語言實現死鎖
讓我來告訴你答案!設置狀態變數lock=0,在佔用資源的函數中,設置lock=1;並在處理結束後設lock=0.
比如:
boollock=0;
intscan()
{
while(lock!=0);//循環檢測,直到資源釋放才執行下面的語句
lock=1;//鎖定資源
...//具體的執行掃描的語句
lock=1;//釋放資源
return0;
}
這個方法容易實現,但是佔用CPU,假定其他線程正在佔用掃描儀,那麼這個線程就會在自己的時間片內不停的執行while語句直到對方釋放掃描儀。由此造成了浪費。
現在流行的做法是通過中斷信號來做,那是一本書的內容,建議看linux內核編程方面的書。
(1)
互斥條件:一個資源每次只能被一個進程使用。
(2)
請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放。
(3)
不剝奪條件:進程已獲得的資源,在末使用完之前,不能強行剝奪。
(4)
循環等待條件:若干進程之間形成一種頭尾相接的循環等待資源關系。
這四個條件是死鎖的必要條件,只要系統發生死鎖,這些條件必然成立,而只要上述條件之一不滿足,就不會發生死鎖。
⑹ 怎麼查看資料庫死鎖,和解決方法
exec sp_lock 快捷鍵 C_2
exec sp_who active exec sp_who快捷鍵 C_1
用Profiler裡面的Locks->Deadlock graph 監控看看,如果看到了死鎖圖,就可以比較形象地展現死鎖發生的過程,還可以看到鎖的具體類型和過程裡面的語句,對你診斷會有幫助。
Declare @LockTab table( spid int,dbid int ,ObjId int,IndId int ,Type varchar(50),Resource varchar(50),Mode varchar(50),Status varchar(50))
insert into @LockTab exec sp_lock
Declare @ActiveTab table(spid int,ecid int,status varchar(50),loginname varchar(50),hostname varchar(50),blk int,dbname varchar(50),cmd varchar(50),request_id int)
insert into @ActiveTab exec sp_who active
select * from @LockTab lt
left join @ActiveTab at on lt.spid=at.spid
⑺ 什麼是死鎖解決死鎖有那幾種策略這些策略分別有哪些實現方法
什麼是死鎖?如果一個進程集合裡面的每個進程都在等待只能由這個集合中的其他一個進程(包括他自身)才能引發的事件,這種情況就是死鎖。這個定義可能有點拗口,一個最簡單的例子就是有資源a和資源b,都是不可剝奪資源,現在進程c已經申請了資源a,進程d也申請了資源b,進程c接下來的操作需要用到資源b,而進程d恰好也在申請資源a,那麼就引發了死鎖。這個肯定每個人都看過了。然後套用回去定義:如果一個進程集合裡面(進程c和進程d)的每個進程(進程c和進程d)都在等待只能由這個集合中的其他一個進程(對於進程c,他在等進程d;對於進程d,他在等進程c)才能引發的事件(釋放相應資源)。這里的資源包括了軟的資源(代碼塊)和硬的資源(例如掃描儀)。資源一般可以分兩種:可剝奪資源(preemptable)和不可剝奪資源(nonpreemptable)。一般來說對於由可剝奪資源引起的死鎖可以由系統的重新分配資源來解決,所以一般來說大家說的死鎖都是由於不可剝奪資源所引起的。死鎖的四個必要條件互斥條件(mutual
exclusion):資源不能被共享,只能由一個進程使用。
請求與保持條件(hold
and
wait):已經得到資源的進程可以再次申請新的資源。
非剝奪條件(no
pre-emption):已經分配的資源不能從相應的進程中被強制地剝奪。
2.檢測死鎖並且恢復。
3.仔細地對資源進行動態分配,以避免死鎖。
4.通過破除死鎖四個必要條件之一,來防止死鎖產生。
⑻ 死鎖的預防是如何實現的
目前,處理死鎖的方法可歸結為以下四種:
1)預防死鎖。這是一種較為簡單和直觀的事先預防的方法。該方法是通過設置某些限制條件,去破壞產生死鎖的四個必要條件中的一個或幾個條件,來預防發生死鎖。預防死鎖是一種較易實現的方法,已被廣泛使用。但由於所施加的限制條件往往太嚴格,因而可能導致系統資源利用率和系統吞吐量降低。
2)避免死鎖。該方法同樣是屬於事先預防策略,但它並不需要事先採取各種限制措施去破壞產生死鎖的四個必要條件,而是在資源的動態分配過程中,用某種方法去防止系統進入不安全狀態,從而避免發生死鎖。這種方法只需事先施加較弱的限制條件,便可獲得較高的資源利用率及系統吞吐量,但在實現上有一定的難度。目前在較完善的系統中常用此方法來避免發生死鎖。
3)檢測死鎖。這種方法並不需要事先採取任何限制性措施,也不必檢查系統是否已經進入不安全區,而是允許系統在運行過程中發生死鎖。但可通過系統所設置的檢測機構,及時的檢測出死鎖的發生,並精確的確定與死鎖有關的進程和資源;然後採取適當措施從系統中將已發生的死鎖清除掉。
4)解除死鎖。這是與檢測死鎖相配套的一種措施。當檢測到系統中已經發生死鎖時,將進程從死鎖狀態中解脫出來。常用的方法是撤銷或掛起一些進程,以便回收一些資源,再將這些資源分配給已經處於阻塞狀態的進程,使之轉為就緒態,以繼續運行。死鎖的檢測和解除措施有可能使系統獲得較好的資源利用率和吞吐量,但是實現上難度也最大。
⑼ 什麼是死鎖 死鎖的處理方法
在並發程序設計中,死鎖 (deadlock) 是一種十分常見的邏輯錯誤。通過採用正確的編程方式,死鎖的發生不難避免。
死鎖的四個必要條件
在計算機專業的本科教材中,通常都會介紹死鎖的四個必要條件。這四個條件缺一不可,或者說只要破壞了其中任何一個條件,死鎖就不可能發生。我們來復習一下,這四個條件是:
•互斥(Mutual exclusion):存在這樣一種資源,它在某個時刻只能被分配給一個執行緒(也稱為線程)使用;
•持有(Hold and wait):當請求的資源已被佔用從而導致執行緒阻塞時,資源佔用者不但無需釋放該資源,而且還可以繼續請求更多資源;
•不可剝奪(No preemption):執行緒獲得到的互斥資源不可被強行剝奪,換句話說,只有資源佔用者自己才能釋放資源;
•環形等待(Circular wait):若干執行緒以不同的次序獲取互斥資源,從而形成環形等待的局面,想像在由多個執行緒組成的環形鏈中,每個執行緒都在等待下一個執行緒釋放它持有的資源。
解除死鎖的必要條件
不難看出,在死鎖的四個必要條件中,第二、三和四項條件比較容易消除。通過引入事務機制,往往可以消除第二、三兩項條件,方法是將所有上鎖操作均作為事務對待,一旦開始上鎖,即確保全部操作均可回退,同時通過鎖管理器檢測死鎖,並剝奪資源(回退事務)。這種做法有時會造成較大開銷,而且也需要對上鎖模式進行較多改動。
消除第四項條件是比較容易且代價較低的辦法。具體來說這種方法約定:上鎖的順序必須一致。具體來說,我們人為地給鎖指定一種類似「水位」的方向性屬性。無論已持有任何鎖,該執行緒所有的上鎖操作,必須按照一致的先後順序從低到高(或從高到低)進行,且在一個系統中,只允許使用一種先後次序。
請注意,放鎖的順序並不會導致死鎖。也就是說,盡管按照 鎖A, 鎖B, 放A, 放B 這樣的順序來進行鎖操作看上去有些怪異,但是只要大家都按先A後B的順序上鎖,便不會導致死鎖。
舉例
假如有三個對象A、B、C,我們人為約定它們的鎖序是: A 先於 B 先於 C。舉例說來,下列鎖序均為合法:
• 鎖C,放C
• 鎖B,放B
• 鎖B,鎖C,放B,放C
• 鎖B,鎖C,放C,放B
• 鎖A,放A
• 鎖A,鎖C,放A,放C
• 鎖A,鎖C,放C,放A
• 鎖A,鎖B,放A,放B
• 鎖A,鎖B,放B,放A
• 鎖A,鎖B,鎖C,放A,放B,放C
• 鎖A,鎖B,鎖C,放C,放B,放A
而在上面定義的系統中,可能導致發生死鎖典型上鎖序列包括:
• 鎖B,鎖A,鎖C,放C,放A,放B
(因為先B後A的上鎖順序違反了鎖序約定,如果另一執行緒同時按照先A後B的順序上鎖,則可能由於執行緒甲獲得了B,執行緒乙獲得了A,而導致雙方同時等待對方釋放所持有的鎖,從而形成死鎖局面;解法是將操作序列中增加適當的鎖操作,即改為鎖B,放B,鎖A,鎖B,鎖C,放C,放A,放B)
或者說,只要拿鎖的時候不出現逆序(例如拿著C的時候試圖抓B或A,或者拿著B的時候試圖抓A),並出現潛在逆序的時候先放掉「小」鎖再抓大的,就一定不造成死鎖了。
⑽ 用C/C++實現死鎖的檢測和解除
參照《操作系統》-》銀行家演算法OK。