定義
進程
進程(Process)是Windows系統中的一個基本概念,它包含著一個運行程序所需要的資源。一個正在運行的應用程序在操作系統中被視為一個進程,進程可以包括一個或多個線程。
程序是在特定操作系統上的可執行文件,它是一個靜態的概念。
而進程可以被認為是程序的一個動態的概念,它有自己的地址空間,能執行一些操作。程序的執行都會伴隨著進程的生成,一個程序的執行會產生一個或多個進程。
線程
線程是進程的一個實體,是獨立運行和獨立調度的基本單位(CPU上真正運行的是線程)。線程自己基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧),但它可與同屬一個進程的其他的線程共享進程所擁有的全部資源。
在.NET中,一般以Main()方法作為入口的,當調用此方法時系統就會自動創建一個主線程。
線程主要是由CPU寄存器、調用棧和線程本地存儲器(Thread Local Storage,TLS)組成的。
CPU寄存器是CPU內部用來存放數據的一些小型存儲區域,用來暫時存放參與運算的數據和運算結果。其實寄存器就是一種常用的時序邏輯電路,但這種時序邏輯電路只包含存儲電路,在線程中主要記錄當前所執行線程的狀態。
調用棧是用來存儲有關正在運行的子程序的返回地址的棧,在此主要用于維護線程所調用到的內存與數據,通過訪問調用棧,可以查找到調用的子程序。
TLS分為靜態和動態兩種,就是基于堆棧的全局變量或者靜態變量來訪問數據,主要用于將將數據和執行的特定的線程聯系起來。
區別
- 進程擁有自己的資源空間,每啟動一個進程,系統就會為它分配地址空間;而線程與CPU資源分配無關,多個線程共享同一進程內的資源,使用相同的地址空間。一個進程可以包含若干個線程。同一進程的線程間可以共享全局變量、靜態變量等數據,而進程之間的通信需要以通信的方式(Inter Process Communication,IPC)進行。不過如何處理好同步與互斥是編寫多線程程序的難點。
- 多進程程序更健壯,多線程程序只要有一個線程死掉,整個進程也死掉了,而一個進程死掉并不會對另外一個進程造成影響,因為進程有自己獨立的地址空間。
- 進程可以通過管道、套接字、信號交互、共享內存、消息隊列等等進行通信;而線程本身就會共享內存,指針指向同一個內容,交互很容易。
多線程
創建多線程步驟:
1、編寫線程所要執行的方法。
2、實例化Thread類,并傳入一個指向線程所要執行方法的委托(ThreadStart或ParameterizedThreadStart)。
Thread thread=new Thread(new ThreadStart(method)),該委托中作為參數的方法不需要參數,并且沒有返回值。也可以分開寫:
ThreadStart threadStart=new ThreadStart(Calculate);
Thread thread=new Thread(threadStart);
ParameterizedThreadStart可以委托一個方法,利用這個方法可以向線程傳遞參數,參數類型必須是Object的。
3、調用Thread實例的Start方法。thread.Start();
線程的屬性
下面程序里列了一些比較常用的屬性。
using System;
using System.Threading;namespace 多線程
{class Program{static void Main(string[] args){Thread thread1 = new Thread(new ThreadStart(Thread1));//thread1.IsBackground = true;//標記為后臺線程thread1.Start();//獲取當前正在運行的線程Thread thread=Thread.CurrentThread;thread.Name = "當前線程";//獲取當前線程的唯一標識符int id = thread1.ManagedThreadId;//獲取當前線程的狀態ThreadState state = thread1.ThreadState;//獲取當前線程的優先級ThreadPriority priority = thread1.Priority;//掛起線程//thread1.Suspend();中止線程//thread1.Abort();string str = 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(str);Console.ReadKey();}static void Thread1(){Console.WriteLine("無參線程!");}}
}
同步
線程的同步是指在同一時間只有一個線程可以訪問變量,對于多線程程序來講,需要使用關鍵字Lock,可以把一段代碼定義為互斥段,互斥段在一個時刻內只允許一個線程進入執行,而其他線程必須等待.
Lock(expression)
{
statement_block
}
如果鎖住一個類的實例,可以使用this,在類內的方法里使用lock (this);
如果鎖住一個靜態變量,一般使用類名.
跨線程訪問
需要使用方法回調完成跨線程.
namespace 多線程1
{public partial class Form1 : Form{public Form1(){InitializeComponent();}//定義回調private delegate void setTextValueCallBack();//聲明回調private setTextValueCallBack a;private void button1_Click(object sender, EventArgs e){//實例化回調a = new setTextValueCallBack(SetValue);//創建一個線程去執行這個方法Thread thread = new Thread(new ThreadStart(Test));//將線程設置為后臺線程thread.IsBackground = true;thread.Start();}private void Test(){//使用回調,invoke方法可以激活控件所在線程,從而調用控件.invoke(回調,參數(調用方法的參數)).invoke表是同步(會等回調方法執行完后再執行下一步)、begininvoke表示異步(不等直接執行下一步)textBox1.Invoke(a);}/// <summary>/// 定義回調使用的方法/// </summary>private void SetValue(){this.textBox1.Text = "1";}}
}
線程池
未完待續
下面線程池講的非常形象.
圖解 | 原來這就是線程池
參考鏈接如下:
C#多線程