[英]What will happen if I skip waiting[i] = false In the following snippet of code?
下面的代碼旨在解決關鍵部分的問題。 假設有N個進程正在其關鍵部分修改公共數據結構。
這些是使用的數據結構:
boolean waiting[n];
boolean lock;
這是testAndSet()函數,由於硬件支持,該函數假定為原子執行。
boolean TestAndSet(boolean *target)
{
boolean rv = *target;
*target = TRUE;
return rv;
}
//以下代碼可確保互斥
do {
waiting[i] = TRUE;
key = TRUE;
while (waiting[i] && key)
key = TestAndSet(&lock);
waiting[i] = FALSE; //what if I skip this??
// critical section
j = ( i + 1) % n ;
while((j != i) && ! waiting[j])
{
j = (j + 1) % n ;
}
if (j == i)
lock = FALSE;
else
waiting[j] = FALSE;
//remainder section
}while (TRUE);
您確實需要在第一時間之后縮進一行。
“ //關鍵部分”下面的內容將解鎖下一個等待訪問的任務,如果沒有人在等待,則釋放鎖定。
如果您不清除等待標志,那么另一個已經鎖定的任務(大概在他們對受保護的內存的訪問周圍運行相同的代碼)將認為您仍在等待,並清除等待標志以使您能夠運行(假設您正坐在循環中,檢查TestAndSet,則等待標志的唯一位置為true)。 而且,由於它只是將鎖有效地傳遞給您,因此它會保持鎖定標志的設置。 但是,如果您的代碼實際上是在未設置false的情況下從那一點開始的,那么您就不能在未將waiting標志設置為True的情況下返回TestAndSet,並且由於lock也保留為true,因此該任務無法實現運行,並且其他任務沒有運行,因為未提前批准下一個任務(或者未將鎖設置為false),並且整個系統現在處於混亂狀態。
如果跳過“ ... = FALSE”行,這意味着您仍在第一個while循環(對於特定i)中等待獲取鎖(關鍵部分),並且會破壞對關鍵對象的“輪循”訪問邏輯在第二個while循環中。
消除那條線可能會破壞整個事情。 緊接其上方的兩行是一個while
循環,它可以終止於以下兩種情況之一: waiting[i]
變為假,或者key
變為假(或者可能都是“同時”)。 如果循環由於key
為假而終止,則waiting[i]
可能仍為真,因此您將陷入既持有鎖又同時認為自己仍在等待鎖的情況,這可能違反了隨后的while
循環...
我想我明白了。 整個混亂是由do while()循環引起的,該循環封裝了整個代碼。 如果這就像代表某個進程的某些函數(例如,
function(int i)
{
waiting[i] = TRUE;
key = TRUE;
while (waiting[i] && key)
key = TestAndSet(&lock);
waiting[i] = FALSE; //what if I skip this??
// critical section
j = ( i + 1) % n ;
while((j != i) && ! waiting[j])
{
j = (j + 1) % n ;
}
if (j == i)
lock = FALSE;
else
waiting[j] = FALSE;
//remainder section
}
假設某個函數在i = 3的情況下被調用(例如,過程i3。對於N = 5)。 並且此過程i3再也不會執行,然后在死鎖情況下不設置waiting [3] = false將會結束。 由於進程i4可能認為進程i3要運行,因此它將通過設置waiting [3] = false而不釋放鎖來結束
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.