文章目錄
一、程序
二、執行緒
三、程序和執行緒的區別與聯絡
四、一個形象的例子解釋程序和執行緒的區別
五、程序/執行緒之間的親緣性
六、協程
一、程序
程序,直觀點說,儲存在硬碟上的程式執行以後,會在記憶體空間裡形成一個獨立的記憶體體,這個記憶體體有自己獨立的地址空間,有自己的堆,上級掛靠單位是作業系統。作業系統會以程序為單位,分配系統資源(CPU時間片、記憶體等資源),程序是資源分配的最小單位。
【程序間通訊(IPC)】:
管道(Pipe)、命名管道(FIFO)、訊息佇列(Message Queue) 、訊號量(Semaphore) 、共享記憶體(Shared Memory);套接字(Socket)。
二、執行緒
執行緒,有時被稱為輕量級程序(Lightweight Process,LWP),是作業系統排程(CPU排程)執行的最小單位。
三、程序和執行緒的區別與聯絡
【區別】
-
排程:執行緒作為排程和分配的基本單位,程序作為擁有資源的基本單位;
-
併發性:不僅程序之間可以併發執行,同一個程序的多個執行緒之間也可併發執行;
-
擁有資源:程序是擁有資源的一個獨立單位,執行緒不擁有系統資源,但可以訪問隸屬於程序的資源。程序所維護的是程式所包含的資源(靜態資源), 如:地址空間,開啟的檔案控制代碼集,檔案系統狀態,訊號處理handler等;執行緒所維護的執行相關的資源(動態資源),如:執行棧,排程相關的控制資訊,待處理的訊號集等;
-
系統開銷:在建立或撤消程序時,由於系統都要為之分配和回收資源,導致系統的開銷明顯大於建立或撤消執行緒時的開銷。但是程序有獨立的地址空間,一個程序崩潰後,在保護模式下不會對其它程序產生影響,而執行緒只是一個程序中的不同執行路徑。執行緒有自己的堆疊和區域性變數,但執行緒之間沒有單獨的地址空間,一個程序死掉就等於所有的執行緒死掉,所以多程序的程式要比多執行緒的程式健壯,但在程序切換時,耗費資源較大,效率要差一些。
【聯絡】
-
一個執行緒只能屬於一個程序,而一個程序可以有多個執行緒,但至少有一個執行緒;
-
資源分配給程序,同一程序的所有執行緒共享該程序的所有資源;
-
處理機分給執行緒,即真正在處理機上執行的是執行緒;
-
執行緒在執行過程中,需要協作同步。不同程序的執行緒間要利用訊息通訊的辦法實現同步。
四、一個形象的例子解釋程序和執行緒的區別
這副圖是一個雙向多車道的道路圖,假如我們把整條道路看成是一個“程序”的話,那麼圖中由白色虛線分隔開來的各個車道就是程序中的各個“執行緒”了。
這些執行緒(車道)共享了程序(道路)的公共資源(土地資源)。
這些執行緒(車道)必須依賴於程序(道路),也就是說,執行緒不能脫離於程序而存在(就像離開了道路,車道也就沒有意義了)。
這些執行緒(車道)之間可以併發執行(各個車道你走你的,我走我的),也可以互相同步(某些車道在交通燈亮時禁止繼續前行或轉彎,必須等待其它車道的車輛通行完畢)。
這些執行緒(車道)之間依靠程式碼邏輯(交通燈)來控制執行,一旦程式碼邏輯控制有誤(死鎖,多個執行緒同時競爭唯一資源),那麼執行緒將陷入混亂,無序之中。
這些執行緒(車道)之間誰先執行是未知的,只有線上程剛好被分配到CPU時間片(交通燈變化)的那一刻才能知道。
五、程序/執行緒之間的親緣性
親緣性的意思是程序/執行緒只在某個cpu上執行(多核系統),比如:
BOOL WINAPI SetProcessAffinityMask(
_In_ HANDLE hProcess,
_In_ DWORD_PTR dwProcessAffinityMask
);
/*
dwProcessAffinityMask 如果是 0 , 代表當前程序只在cpu0 上工作;
如果是 0x03 , 轉為2進位制是 00000011 . 代表只在 cpu0 或 cpu1上工作;
*/
使用CPU親緣性的好處:設定CPU親緣性是為了防止程序/執行緒在CPU的核上頻繁切換,從而避免因切換帶來的CPU的L1/L2 cache失效,cache失效會降低程式的效能。
六、協程
協程,是一種比執行緒更加輕量級的存在,協程不是被作業系統核心所管理,而完全是由程式所控制(也就是在使用者態執行)。這樣帶來的好處就是效能得到了很大的提升,不會像執行緒切換那樣消耗資源。
子程式,或者稱為函式,在所有語言中都是層級呼叫,比如A呼叫B,B在執行過程中又呼叫了C,C執行完畢返回,B執行完畢返回,最後是A執行完畢。所以子程式呼叫是透過棧實現的,一個執行緒就是執行一個子程式。子程式呼叫總是一個入口,一次返回,呼叫順序是明確的。而協程的呼叫和子程式不同。
協程在子程式內部是可中斷的,然後轉而執行別的子程式,在適當的時候再返回來接著執行。
def A():
print '1'
print '2'
print '3'
def B():
print 'x'
print 'y'
print 'z'
假設由協程執行,在執行A的過程中,可以隨時中斷,去執行B,B也可能在執行過程中中斷再去執行A,結果可能是:1 2 x y 3 z。
協程的特點在於是一個執行緒執行,那和多執行緒比,協程有何優勢?
-
極高的執行效率:因為子程式切換不是執行緒切換,而是由程式自身控制,因此,沒有執行緒切換的開銷,和多執行緒比,執行緒數量越多,協程的效能優勢就越明顯;
-
不需要多執行緒的鎖機制:因為只有一個執行緒,也不存在同時寫變數衝突,在協程中控制共享資源不加鎖,只需要判斷狀態就好了,所以執行效率比多執行緒高很多。
原文連結:https://blog.csdn.net/daaikuaichuan/article/details/82951084