熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

詳解.NET編程過程中的線程沖突[1]

2013-11-13 12:16:50  來源: .NET編程 

  什麼是線程沖突

  線程沖突其實就是指兩個或以上的線程同時對同一個共享資源進行操作而造成的問題

  一個比較經典的例子是用一個全局變量做計數器然後開N個線程去完成某個任務每個線程完成一次任務就將計數器加一直到完成次任務如果不考慮線程沖突問題用類似下面的代碼去做則很可能會超額完成任務線程越多完成任務次數超出次的可能性就越大

  偽代碼如下

int count = ;//全局計數器
void ThreadMethod()//運行在每個線程的方法
{
while( true )
{
if ( count >= )//如果達到任務指標
break;//中斷線程執行
DoSomething();//完成某個任務
count++;
}
}
//省略線程的創建等代碼

  具體的為什麼會超額完成任務的原因在這裡我就不贅述了這個例子在單線程環境中是絕對不會超額完成任務的

  當然在這個例子中將count++放到if語句中也許能降低一些事故發生的概率但那不是絕對的換言之這樣的程序不能杜絕超額完成任務的可能

  其實從線程沖突的定義中我們不難發現要造成線程沖突有兩個必要條件多線程和共享資源這兩個條件中有一個不成立就不可能發生線程沖突問題

  所以在單線程環境中是不存在線程沖突的問題的不過很可惜的是我們的軟件早已進化到了多進程多線程的時代單線程的程序幾乎是不存在的無論是WinForm還是WebForm程序運行的環境都是多線程的而不論你自己是不是明確的開啟了一個線程

  既然多線程是不可避免的那麼要避免線程沖突就只能從共享資源來開刀了

  線程安全的資源

  如果大家經常看MSDN或者VS幫助中的NET類庫參考的話就不難發現幾乎所有的類型都有這麼一句話的描述此類型的任何公共 static(在 Visual Basic中為 Shared) 成員都是線程安全的但不保證所有實例成員都是線程安全的那麼線程安全到底是什麼意思?

  其實線程安全很簡單就是指一個函數(方法屬性字段或者別的)在同一時間被不同線程使用不會造成任何線程沖突的問題就說這個東西是線程安全的

  接下來來談談什麼樣的資源是線程安全的

  之所以使用資源這個詞是因為線程沖突不僅僅會發生在共享的變量上兩個線程同時對同一個文件進行讀寫兩個程序同時用同一個端口與同一個地址進行通信都會造成線程沖突只不過是操作系統和幫我們協調了這些沖突而已

  一個線程安全的資源即是指在不同線程中使用不會導致線程沖突問題的資源

  一個不能被改變的資源是線程安全的比如說一個常量

const decimal pai = ;//C++: const double pai = ;

  因為pai的值不可能被改變所以在不同的線程中使用也不會造成沖突換言之它在不同的線程中同時被使用和在一個線程中被使用是沒有區別的所以這個東西是線程安全的

  同樣的NET中一個字符串的實例也是線程安全的因為字符串的實例在NET中也是不可以被改變的一個字符串的實例一旦被創建對其所有的屬性方法調用的結果都是唯一確定的永遠不會改變的所以NET類庫參考中String類型才有此類型是線程安全的與之類似的Type類型Assembly類型都是線程安全的

  但string的實例是線程安全的卻不代表string的變量是線程安全的換言之假設有一個靜態變量

public static string str = ;

  str不是線程安全的因為str這個變量的字符串實例可以被任何線程修改

  再考慮這樣的例子

public static readonly SqlConnection connection = new SqlConnection( connectionString );

  雖然connection本身雖然是線程安全的但connection的任何成員都不是線程安全的

[]  []  []  


From:http://tw.wingwit.com/Article/program/net/201311/15566.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.