最近發現看過的東西經常記不住,想想應該定期追溯下,寫寫學習筆記,看來真的老了- -。
最近項目裡面的兄弟們被各種並行作業,多線程操作搞的頗為狼狽,這部分的只是很有必要多多學習下(其實我個人認為還是由於一些需求策划上的不理智,自己給自己製造並發的麻煩,如果有個稍微妥協的決定,結果一定能好很多。)
線程增加了系統的健壯性和cpu的充分的利用,但是其自身的環境切換還是有很大的開銷。具體參看作業系統書籍。
CLR的一個進程內會維護一個線程池,線程池被該進程內所有應用程式定義域共用。線程池分為兩類,一類是work thread( compute-bound operation,計算密集型線程),一類是IO thread( I/O-bound operation,IO密集型),IO密集型線程可以在不佔用CPU的情況下通過裝置驅動程式進行IO操作,比如帶BeginXXX和endxxx方法的檔案操作,網路訪問等類型。
線程池大概的工作情況是這樣,當開始線程池裡面沒有線程的情況下,當有應用程式需要線程池中線程進行工作,線程池將會建立一個線程進行工作,之後到來的請求,線程池都會盡量使用這個線程進行響應,如果請求過多的話,線程池將會建立新的線程進行響應直到達到上限。當線程池中的線程處於空閑狀態一定時間後(具體多少看環境)線程池池內的空閑線程將會進行自我終結。
線程池的使用方法,最簡單可以這樣,當然有個重要的缺陷是我們無法知道該委託的操作什麼時候完成,有沒有報錯。
ThreadPool.QueueUserWorkItem(p =>
{
Console.WriteLine("do something");
});
當然還可以使用using System.Threading.Tasks下的task類,在CLR VIA C# 3rd中對此有很詳細的介紹,這也是第3版比起第2版多的部分,而且多了很多,剛剛下載,得仔細看看。
非同步作業其實更多時候還是使用APM模式,也就是通過委託的BeginInvoke和endinvoke,或者是支援IO非同步各種其他方法。
錯誤的用法:
1、線上程池中調用thread.sleep會導致該線程池中的線程掛起,無法回到池中,當然無法分擔其他任務。
2、調用beginvoke卻不調用endinvoke也會使得資源無法回收。
3、注意在非同步作業中的錯誤處理,如果不捕獲會導致該所屬進程崩潰。
累。。。明天繼續寫。。。