這篇文章主要介紹了c#中lock死鎖的用法,對於共享資源的訪問及c#程式設計的安全性而言,有著非常重要的意義!需要的朋友可以參考下
lock的使用原型是:?1
234lock
(x)
首先要明白為什麼上面這段話能夠鎖定**,其中的奧妙就是x這個物件,事實上x是任意一種引用型別,它在這兒起的作用就是任何執行緒執行到lock(x)時候,x需要獨享才能執行下面的**,若假定現在有3個執行緒a,b,c都執行到了lock(x)而abc因為此時都占有x,這時abc就要停下來排個隊,乙個乙個使用x,從而起到在下面的**塊內只有乙個執行緒在執行(因為此時只有乙個執行緒獨享x,其餘兩個在排隊),所以這個x必須是所有要執行臨界區域**程序必須共有的乙個資源,從而起到抑制執行緒的作用。
下面再來談談lock使用中會遇到和注意的問題,lock最需要注意的乙個問題就是執行緒死鎖!
在msdn上列出了3個典型問題:
通常,應避免鎖定 public 型別,否則例項將超出**的控制範圍。常見的結構 lock (this)、lock (typeof (mytype)) 和 lock ("mylock") 違反此準則:
如果例項可以被公共訪問,將出現 lock (this) 問題。
如果 mytype 可以被公共訪問,將出現 lock (typeof (mytype)) 問題。
由於程序中使用同一字串的任何其他**將共享同乙個鎖,所以出現 lock(「mylock」) 問題。
最佳做法是定義 private 物件來鎖定, 或 private shared 物件變數來保護所有例項所共有的資料。
(1)lock (this) 問題:
假定有兩個類: ?1
2class
a{}
class
b{}
有兩個公共物件: ?1
2a a=
new
a();
b b=
new
b();
首先在a中若有一函式內的**需要鎖定:
**1: ?1
2345
678lock
(
this
)
//this在這裡就是a
}
然而此時b中某函式也有如下**需要鎖定:
**2: ?1
2345
678lock
(
this
)
//this在這裡就是b
}
設想一下上面兩段**在兩個執行緒下同時執行會有什麼後果?
結果就是,**1執行到lock(this)後a被鎖定,**2執行到lock(this)後b被鎖定,然後**1需求b,**2需求a,此時兩個需求都被相互占有出現僵持狀態,程式死鎖了。
(2)lock(typeof (mytype))問題:
假定有兩個公共變數:?1
int
a;
float
b;
下面看如下**
**3:?1
2345
678lock
(
typeof
(a))
//typeof(a)就是system.type.int型別
}
又有如下**:
**4:?1
2345
678lock
(
typeof
(b))
//typeof(b)就是system.type.float型別
}
若有兩個程序分別同時進入上面兩個**外層的lock,就分別鎖定了system.type.int和system.type.float,而馬上它們又需求system.type.float和system.type.int,彼此相互占有,彼此僵持,程式進入死鎖狀態!
(3)字串問題 :
在闡述這個問題之前,有乙個知識大家必須知道:c#中字串被公共語言執行庫 (clr)「暫留」。這意味著整個程式中任何給定字串都只有乙個例項,就是這同乙個物件表示了所有執行的應用程式域的所有執行緒中的該文字。因此,只要在應用程式程序中的任何位置處具有相同內容的字串上放置了鎖,就將鎖定應用程式中該字串的所有例項。
言下之意就是假定有兩個類分別有兩個字串:?1
2345
6789
1011
class
a
class
c
事實上a和c引用的是同乙個字串"abc",b和d引用的是同乙個字串"def"
現在如果在兩個類中有如下**
在類a中有**5: ?1
2345
678lock
(b)
//b是"def"
}
在類b中有**6: ?1
2345
678lock
(c)
//c是"abc"
}
那麼**5和**6同時有兩個執行緒執行結果可想而知:在兩個執行緒執行到外層lock**時"def"和"abc"被鎖定。接著他們在內部lock處同時需求"abc"和"def",而此時兩個字串被兩個程序彼此占有,程式又死鎖了!所以msdn說:鎖定字串尤其危險!最好不要使用!
msdn最後說了:最佳做法是定義 private 物件來鎖定, 或 private shared 物件變數來保護所有例項所共有的資料。
在個人看來,也不是絕對安全,這裡就舉出乙個例子:
假定有乙個類: ?1
2345
6789
1011
1213
1415
1617
1819
2021
2223
2425
2627
class
a
}
}
public
void
y()
}
}
}
現在假定有兩個執行緒同時執行函式x()和y();結果private物件a和b分別在外層lock鎖定,接著兩個執行緒在內部又立馬需求b和a,a,b彼此占有又彼此需求,程式死鎖。
所以具體要看情況而定,但是定義 private 物件來鎖定至少可以降低風險。
awk例項教程
1.awk語法規則 awk 2.顯示最近登入的5個帳號 last n 5 awk root root root dmtsai root awk工作流程是這樣的 讀入有 n 換行符分割的一條記錄,然後將記錄按指定的域分隔符劃分域,填充域,0則表示所有域,1表示第乙個域,n表示第n個域。預設域分隔符是 ...
CSS reflow例項教程
frame主要的動作有三個 構造frame,以建立物件樹 dom樹 reflow,以確定物件位置,或者www.cppcns.com是呼叫mozilla的layout 這裡是指原始碼的實現 繪製,以便物件能顯示在螢幕上 總的來說,reflow就是載入內容樹 在html中就是dom樹 和建立或更新fra...
php小偷例項教程
以 http mtv.8391.com 為例,偷取mtv名稱 歌手 路徑 1 對原 進行 分析 檢視其原檔案,判斷出呼叫mtv路徑的檔案 利用 檢視程式,取得 http mtv.8391.com yxwen.asp?id 3488頁面 3488為隨機,只是了解頁面 2 對要偷取的頁面進行 分析 ht...