一、操作系統用進程(Processe)分隔正在執行的程式,用線程(Thread)作為操作系統分配處理器時間的基本單元,進程上下文中可以運行多個線程,進程的所有線程共用其虛擬地址空間,所有線程均可執行程式代碼中的任意部分,包括其他線程正在執行的代碼; 1.預設情況下,.NET程式只啟動單個線程,被稱為 ...
一、操作系統用進程(Processe)分隔正在執行的程式,用線程(Thread)作為操作系統分配處理器時間的基本單元,進程上下文中可以運行多個線程,進程的所有線程共用其虛擬地址空間,所有線程均可執行程式代碼中的任意部分,包括其他線程正在執行的代碼;
1.預設情況下,.NET程式只啟動單個線程,被稱為主線程(Primary Thread),也可以在運行時開啟其它線程,與主線程並行同時執行代碼,這些線程被稱為工作線程(Worker Thread);由.Net開啟和管理的線程通常稱為托管線程(Managed Thread);
2.托管線程又分為前臺線程和後臺線程,兩者類似,但前臺線程會阻止進程停止,而後臺線程不會,即當進程的Main方法結束後,只有在所有前臺線程都停止時,CLR才會結束該進程,此時會對仍處於活動狀態的後臺線程調用Abort方法來結束所有後臺進程;
※關閉程式如遇到無法關閉所有線程時,可以在Main方法結束前通過以下代碼強制關閉所有線程,詳見:
System.Environment.Exit(0);
二、在使用多線程時,不同線程不僅可以同時執行同一段代碼,還可以同時訪問同一記憶體中的數據,所以會存在一定的數據衝突問題,稱為爭用條件(Race Condition):
static int MyNum; static int RaceConditionCount; static void MyFunc() { while (true) { if (MyNum == 0) { MyNum++; if (MyNum == 0) { RaceConditionCount++; //只有在出現爭用條件時才會執行此語句 } } MyNum = 0; } } static void Main(string[] args) { for (int i = 0; i < 2; i++) { Thread thread = new Thread(MyFunc); thread.Start(); } Thread.Sleep(1000); Console.WriteLine(RaceConditionCount); //輸出1秒內產生爭用條件的次數 Console.Read(); }
1.對於爭用條件的發生頻率,發佈版本比調試版本的出現次數多(發佈版本編譯出的代碼被優化過而且開啟了JIT優化),多核CPU比單核CPU的出現次數多(多核CPU中多個線程可以同時運行,單核CPU的線程調度是搶占式的,也會出現此問題,只是次數較少);
三、為了避免產生爭用條件,需要註意數據的同步問題,可以通過給對象加鎖,使同一時間內只有一個線程可以執行加鎖對象所鎖定的代碼;
如果您覺得閱讀本文對您有幫助,請點一下“推薦”按鈕,您的認可是我寫作的最大動力!
作者:Minotauros
出處:https://www.cnblogs.com/minotauros/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。