進程和線程(線程是輕量級進程)(上)


簡介

進程(Process)是Windows系統中的一個基本概念,它包含着一個運行程序所需要的資源。一個正在運行的應用程序在操作系統中被視為一個進程,進程可以包括一個或多個線程。線程是操作系統分配處理器時間的基本單元,在進程中可以有多個線程同時執行代碼。進程之間是相對獨立的,一個進程無法訪問另一個進程的數據(除非利用分布式計算方式),一個進程運行的失敗也不會影響其他進程的運行,Windows系統就是利用進程把工作划分為多個獨立的區域的。進程可以理解為一個程序的基本邊界。是應用程序的一個運行例程,是應用程序的一次動態執行過程。

線程(Thread)是進程中的基本執行單元,是操作系統分配CPU時間的基本單位,一個進程可以包含若干個線程,在進程入口執行的第一個線程被視為這個進程的主線程。在.NET應用程序中,都是以Main()方法作為入口的,當調用此方法時系統就會自動創建一個主線程。線程主要是由CPU寄存器、調用棧和線程本地存儲器(Thread Local Storage,TLS)組成的。CPU寄存器主要記錄當前所執行線程的狀態,調用棧主要用於維護線程所調用到的內存與數據,TLS主要用於存放線程的狀態信息。

多線程優點:

    可以同時執行多個計算任務,有可能提高計算機的處理能力,使得計算機每秒能執行越來越多的命令

多線程缺點:

(1)線程也是程序,所以線程需要占用內存,線程越多,占用內存也越多。

(2)多線程需要協調和管理,所以需要占用CPU時間以便跟蹤線程。

(3)線程之間對共享資源的訪問會相互影響,必須解決爭用共享資源的問題。

(4)線程太多會導致控制太復雜,最終可能造成很多程序缺陷。

進程

1、獲取當前程序中正在運行的所有進程
1 //獲取本機所有進程
2 Process[] pro = Process.GetProcesses(); 3 foreach (Process p in pro) 4 { 5  Console.WriteLine(p.ProcessName); 6 }

2、殺死進程:調用Process.Kill()方法

1 //獲取本機所有進程
2 Process[] pro = Process.GetProcesses(); 3 foreach (Process p in pro) 4 { 5     //終止進程
6  p.Kill(); 7  Console.WriteLine(p.ProcessName); 8 }

3、通過進程打開應用程序

1 //通過進程打開應用程序
2 Process.Start("calc"); 3 Process.Start("mspaint"); 4 Process.Start("notepad"); 5 Process.Start("iexplore", "http://www.baidu.com");

4、通過一個進程打開指定的文件

1 ProcessStartInfo psi = new ProcessStartInfo(@"C:\Users\Lenovo\Desktop\html.txt"); 2 Process p = new Process(); 3 p.StartInfo = psi; 4 p.Start();

線程生命周期

線程生命周期開始於 System.Threading.Thread 類的對象被創建時,結束於線程被終止或完成執行時。

下面列出了線程生命周期中的各種狀態:

  • 未啟動狀態:當線程實例被創建但 Start 方法未被調用時的狀況。

  • 就緒狀態:當線程准備好運行並等待 CPU 周期時的狀況。

  • 不可運行狀態下面的幾種情況下線程是不可運行的。

  • 死亡狀態:當線程已完成執行或已中止時的狀況。

    • 已經調用 Sleep 方法

    • 已經調用 Wait 方法

    • 通過 I/O 操作阻塞

主線程

在 C# 中,System.Threading.Thread 類用於線程的工作。它允許創建並訪問多線程應用程序中的單個線程。進程中第一個被執行的線程稱為主線程

當 C# 程序開始執行時,主線程自動創建。使用 Thread 類創建的線程被主線程的子線程調用。可以使用 Thread 類的 CurrentThread 屬性訪問線程。

Thread 類常用的屬性和方法

下表列出了 Thread 類的一些常用的 屬性

屬性 描述
CurrentContext 獲取線程正在其中執行的當前上下文。
CurrentCulture 獲取或設置當前線程的區域性。
CurrentPrinciple 獲取或設置線程的當前負責人(對基於角色的安全性而言)。
CurrentThread 獲取當前正在運行的線程。
CurrentUICulture 獲取或設置資源管理器使用的當前區域性以便在運行時查找區域性特定的資源。
ExecutionContext 獲取一個 ExecutionContext 對象,該對象包含有關當前線程的各種上下文的信息。
IsAlive 獲取一個值,該值指示當前線程的執行狀態。
IsBackground 獲取或設置一個值,該值指示某個線程是否為后台線程。
IsThreadPoolThread 獲取一個值,該值指示線程是否屬於托管線程池。
ManagedThreadId 獲取當前托管線程的唯一標識符。
Name 獲取或設置線程的名稱。
Priority 獲取或設置一個值,該值指示線程的調度優先級。
ThreadState 獲取一個值,該值包含當前線程的狀態。

下表列出了 Thread 類的一些常用的 方法

序號 方法名 & 描述
1 public void Abort()
在調用此方法的線程上引發 ThreadAbortException,以開始終止此線程的過程。調用此方法通常會終止線程。
2 public static LocalDataStoreSlot AllocateDataSlot()
在所有的線程上分配未命名的數據槽。為了獲得更好的性能,請改用以 ThreadStaticAttribute 屬性標記的字段。
3 public static LocalDataStoreSlot AllocateNamedDataSlot( string name) 
在所有線程上分配已命名的數據槽。為了獲得更好的性能,請改用以 ThreadStaticAttribute 屬性標記的字段。
4 public static void BeginCriticalRegion()
通知主機執行將要進入一個代碼區域,在該代碼區域內線程中止或未經處理的異常的影響可能會危害應用程序域中的其他任務。
5 public static void BeginThreadAffinity()
通知主機托管代碼將要執行依賴於當前物理操作系統線程的標識的指令。
6 public static void EndCriticalRegion()
通知主機執行將要進入一個代碼區域,在該代碼區域內線程中止或未經處理的異常僅影響當前任務。
7 public static void EndThreadAffinity()
通知主機托管代碼已執行完依賴於當前物理操作系統線程的標識的指令。
8 public static void FreeNamedDataSlot(string name)
為進程中的所有線程消除名稱與槽之間的關聯。為了獲得更好的性能,請改用以 ThreadStaticAttribute 屬性標記的字段。
9 public static Object GetData( LocalDataStoreSlot slot ) 
在當前線程的當前域中從當前線程上指定的槽中檢索值。為了獲得更好的性能,請改用以 ThreadStaticAttribute 屬性標記的字段。
10 public static AppDomain GetDomain()
返回當前線程正在其中運行的當前域。
11 public static AppDomain GetDomainID()
返回唯一的應用程序域標識符。
12 public static LocalDataStoreSlot GetNamedDataSlot( string name ) 
查找已命名的數據槽。為了獲得更好的性能,請改用以 ThreadStaticAttribute 屬性標記的字段。
13 public void Interrupt()
中斷處於 WaitSleepJoin 線程狀態的線程。
14 public void Join()
在繼續執行標准的 COM 和 SendMessage 消息泵處理期間,阻塞調用線程,直到某個線程終止為止。此方法有不同的重載形式。
15 public static void MemoryBarrier()
按如下方式同步內存存取:執行當前線程的處理器在對指令重新排序時,不能采用先執行 MemoryBarrier 調用之后的內存存取,再執行 MemoryBarrier 調用之前的內存存取的方式。
16 public static void ResetAbort()
取消為當前線程請求的 Abort。
17 public static void SetData( LocalDataStoreSlot slot, Object data ) 
在當前正在運行的線程上為此線程的當前域在指定槽中設置數據。為了獲得更好的性能,請改用以 ThreadStaticAttribute 屬性標記的字段。
18 public void Start()
開始一個線程。
19 public static void Sleep( int millisecondsTimeout ) 
讓線程暫停一段時間。
20 public static void SpinWait( int iterations ) 
導致線程等待由 iterations 參數定義的時間量。
21 public static byte VolatileRead( ref byte address )
public static double VolatileRead( ref double address )
public static int VolatileRead( ref int address )
public static Object VolatileRead( ref Object address ) 

讀取字段值。無論處理器的數目或處理器緩存的狀態如何,該值都是由計算機的任何處理器寫入的最新值。此方法有不同的重載形式。這里只給出了一些形式。
22 public static void VolatileWrite( ref byte address, byte value )
public static void VolatileWrite( ref double address, double value )
public static void VolatileWrite( ref int address, int value )
public static void VolatileWrite( ref Object address, Object value ) 

立即向字段寫入一個值,以使該值對計算機中的所有處理器都可見。此方法有不同的重載形式。這里只給出了一些形式。
23 public static bool Yield()
導致調用線程執行准備好在當前處理器上運行的另一個線程。由操作系統選擇要執行的線程。
24 public void Suspend();(慎用)
掛起線程,或者如果線程已掛起,則不起作用。
25 public void Resume();(慎用)
繼續已掛起的線程。

線程優先級

成員名稱

說明

Lowest

可以將 Thread 安排在具有任何其他優先級的線程之后。

BelowNormal

可以將 Thread 安排在具有 Normal 優先級的線程之后,在具有 Lowest 優先級的線程之前。

Normal

默認選擇。可以將 Thread 安排在具有 AboveNormal 優先級的線程之后,在具有 BelowNormal 優先級的線程之前

AboveNormal

可以將 Thread 安排在具有 Highest 優先級的線程之后,在具有 Normal 優先級的線程之前。

Highest

可以將 Thread 安排在具有任何其他優先級的線程之前。

線程示例

static void Main(string[] args) { //獲取正在運行的線程
            Thread thread = Thread.CurrentThread; //設置線程的名字
            thread.Name = "主線程"; //獲取當前線程的唯一標識符
            int id = thread.ManagedThreadId; //獲取當前線程的狀態
            ThreadState state= thread.ThreadState; //獲取當前線程的優先級
            ThreadPriority priority= thread.Priority; string strMsg = string.Format("Thread ID:{0}\n" + "Thread Name:{1}\n" +
                "Thread State:{2}\n" + "Thread Priority:{3}\n", id, thread.Name, state, priority); Console.WriteLine(strMsg); Console.ReadKey(); }

運行結果:

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM