談到線程(Thread),大家應該不會陌生。和他相近的還有一個進程的概念(Process)。那首先我們先來熟悉他們的概念,以及他們之間的關系。
什麼是進程?
當一個程序開始運行時,它就是一個進程,進程包括運行中的程序和程序所使用到的內存和系統資源。
而一個進程又是由多個線程所組成的。
什麼是線程?
線程是程序中的一個執行流,每個線程都有自己的專有寄存器(棧指針、程序計數器等),但代碼區是共享的,即不同的線程可以執行同樣的函數。
他們的關系?
線程根進程既有聯系又有區別。進程是代碼在數據集的一次執行,是系統資源分配的基本單位。任何一個線程必然在一個進程中運行;而一個進程至少擁有一個線程,否則無法執行。事實上,每個進程都有一個主線程,該線程所擁有的其他線程都是由主線程創建的。如果我們s結束一個進程的主線程,就會結束該進程的所有其他線程,也就結束整個進程!
我們可以這麼理解:真正去運行代碼是線程!而進程只是為運行代碼配置所運行的系統資源。幾個線程共同運行完成某項功能,組織了一次代碼執行過程!這樣就有了進程!
C#裡面是Thread類來表示線程的!那我們先來看看Thread類的定義。
[ComVisibleAttribute(true)]
[ClassInterfaceAttribute(ClassInterfaceType.None)]
public sealed class Thread : CriticalFinalizerObject,
_Thread
{
...
}
[ComVisibleAttribute(true)]這個表示控制程序集中個別托管類型、成員或所有類型對COM 的可訪問性。
[ClassInterfaceAttribute(ClassInterfaceType.None)]為公開給COM 的類指定要生成的類接口的類型(如果有接口生成)。
在從CriticalFinalizerObject 類派生的類中,公共語言運行庫(CLR) 保證所有關鍵終止代碼都有機會執行,即使是在CLR 強行卸載應用程序域或中止線程的情況中(只要終結器遵守CER 的規則);
_Thread此接口用於從非托管代碼訪問托管類,不應從托管代碼調用。
這裡注意的Thread類在.net是聲明sealed,他是無法被繼承的!這和Java的區別挺大的!
他有4個構造函數,我們主要看下其中兩個就行了!
[SecuritySafeCritical]
public Thread(ParameterizedThreadStart start);
[SecuritySafeCritical]
public Thread(ThreadStart start);
ParameterizedThreadStart 和ThreadStart都為一個委托,其中第一個委托表示帶參數的委托,類型為obj,後面一個為不帶參數的委托。他們都被標記了[ComVisible(false)]表示不能對COM+進行訪問!
通過Thread的一些靜態屬性能夠得到當前的上下文,當前運行的進程等等!通過他的靜態方法能獲得他的運行應用域等等!
下面我們看個例子,
1 class Program
2 {
3 static void Main(string[] args)
4 {
5 ThreadStart tspx = new ThreadStart(PrintX);
6 ThreadStart tspy = new ThreadStart(PrintY);
7 ParameterizedThreadStart ptsp = new ParameterizedThreadStart(PrintParam);
8 Thread t1 = new Thread(tspx);
9 Thread t2 = new Thread(tspy);
10 Thread t3 = new Thread(ptsp);
11
12 t1.Start();
13 t2.Start();
14 t3.Start("123");
15 Thread.Sleep(300);
16
17 }
18 public static void PrintX()
19 {
20 int i = 1;
21 while (i++<50)
22 {
23 Console.Write("X");
24 }
25 }
26 public static void PrintY()
27 {
28 int i = 1;
29 while (i++ < 50)
30 {
31 Console.Write("Y");
32 }
33 }
34 public static void PrintParam(object s)
35 {
36 int i = 1;
37 while (i++ < 50)
38 {
39 Console.Write(s.ToString());
40 }
41 }
42
43 }
例子是比較簡單,運行之後的結果往往比較隨機的!只需要把運行的次數調高點就可!注意ParameterizedThreadStart這個參數是Object類型的!從這個例子可看出,這些線程是雜亂的運行的!只要將主線程結束,整個應用程序就會結束,而結束其他線程則不會!
請看下面的例子,
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading;
6
7 namespace ConsoleApplication3
8 {
9 class Program
10 {
11 static void Main(string[] args)
12 {
13 Thread t = new Thread(PrintX);
14 t.Start();
15 Thread.CurrentThread.Name = "Main";
16 Console.WriteLine("主線程的應用域{0},ID為{1}", Thread.GetDomain().ToString(), Thread.GetDomainID());
17 Console.WriteLine("主線程的名字為{0},HashCode為{1}", Thread.CurrentThread.Name, Thread.CurrentThread.GetHashCode());
18
19 }
20 static void PrintX ()
21 {
22 Thread.CurrentThread.Name = "t1";
23 Console.WriteLine("t1線程的應用域{0},ID為{1}", Thread.GetDomain().ToString(), Thread.GetDomainID());
24 Console.WriteLine("t1線程的名字為{0},HashCode為{1}", Thread.CurrentThread.Name, Thread.CurrentThread.GetHashCode());
25 }
26 }
27 }
這個例子運行如下圖所示,
這裡,通Thread的一些靜態屬性可以獲得我們一些想要的東西!這一點在平時用的也比較多!
好了,今天就寫了這麼多了!