程式、執行緒和協程之間的區別和聯絡
一、程式
程式,直觀點說,儲存在硬碟上的程式執行以後,會在記憶體空間裡形成一個獨立的記憶體體,這個記憶體體有自己獨立的地址空間,有自己的堆,上級掛靠單位是作業系統。作業系統會以程式為單位,分配系統資源(CPU時間片、記憶體等資源),程式是資源分配的最小單位。
【程式間通訊(IPC)】:
- 管道(Pipe)、命名管道(FIFO)、訊息佇列(Message Queue) 、訊號量(Semaphore) 、共享記憶體(Shared Memory);套接字(Socket)。
二、執行緒
執行緒,有時被稱為輕量級程式(Lightweight Process,LWP),是作業系統排程(CPU排程)執行的最小單位。
三、程式和執行緒的區別與聯絡
【區別】:
-
排程:執行緒作為排程和分配的基本單位,程式作為擁有資源的基本單位;
-
併發性:不僅程式之間可以併發執行,同一個程式的多個執行緒之間也可併發執行;
-
擁有資源:程式是擁有資源的一個獨立單位,執行緒不擁有系統資源,但可以訪問隸屬於程式的資源。程式所維護的是程式所包含的資源(靜態資源), 如:地址空間,開啟的檔案控制程式碼集,檔案系統狀態,訊號處理handler等;執行緒所維護的執行相關的資源(動態資源),如:執行棧,排程相關的控制資訊,待處理的訊號集等;
-
系統開銷:在建立或撤消程式時,由於系統都要為之分配和回收資源,導致系統的開銷明顯大於建立或撤消執行緒時的開銷。但是程式有獨立的地址空間,一個程式崩潰後,在保護模式下不會對其它程式產生影響,而執行緒只是一個程式中的不同執行路徑。執行緒有自己的堆疊和區域性變數,但執行緒之間沒有單獨的地址空間,一個程式死掉就等於所有的執行緒死掉,所以多程式的程式要比多執行緒的程式健壯,但在程式切換時,耗費資源較大,效率要差一些。
【聯絡】:
-
一個執行緒只能屬於一個程式,而一個程式可以有多個執行緒,但至少有一個執行緒;
-
資源分配給程式,同一程式的所有執行緒共享該程式的所有資源;
-
處理機分給執行緒,即真正在處理機上執行的是執行緒;
-
執行緒在執行過程中,需要協作同步。不同程式的執行緒間要利用訊息通訊的辦法實現同步。
四、一個形象的例子解釋程式和執行緒的區別
這副圖是一個雙向多車道的道路圖,假如我們把整條道路看成是一個“程式”的話,那麼圖中由白色虛線分隔開來的各個車道就是程式中的各個“執行緒”了。
-
這些執行緒(車道)共享了程式(道路)的公共資源(土地資源)。
-
這些執行緒(車道)必須依賴於程式(道路),也就是說,執行緒不能脫離於程式而存在(就像離開了道路,車道也就沒有意義了)。
-
這些執行緒(車道)之間可以併發執行(各個車道你走你的,我走我的),也可以互相同步(某些車道在交通燈亮時禁止繼續前行或轉彎,必須等待其它車道的車輛通行完畢)。
-
這些執行緒(車道)之間依靠程式碼邏輯(交通燈)來控制執行,一旦程式碼邏輯控制有誤(死鎖,多個執行緒同時競爭唯一資源),那麼執行緒將陷入混亂,無序之中。
-
這些執行緒(車道)之間誰先執行是未知的,只有線上程剛好被分配到CPU時間片(交通燈變化)的那一刻才能知道。
五、程式/執行緒之間的親緣性
親緣性的意思是程式/執行緒只在某個cpu上執行(多核系統),比如:
<span style="color:#000000"><code class="language-cpp">BOOL WINAPI <span style="color:#61aeee">SetProcessAffinityMask</span><span style="color:#999999">(</span>
_In_ HANDLE hProcess<span style="color:#999999">,</span>
_In_ DWORD_PTR dwProcessAffinityMask
<span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#5c6370">/*
dwProcessAffinityMask 如果是 0 , 代表當前程式只在cpu0 上工作;
如果是 0x03 , 轉為2進位制是 00000011 . 代表只在 cpu0 或 cpu1上工作;
*/</span>
</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
使用CPU親緣性的好處:設定CPU親緣性是為了防止程式/執行緒在CPU的核上頻繁切換,從而避免因切換帶來的CPU的L1/L2 cache失效,cache失效會降低程式的效能。
六、協程
協程,是一種比執行緒更加輕量級的存在,協程不是被作業系統核心所管理,而完全是由程式所控制(也就是在使用者態執行)。這樣帶來的好處就是效能得到了很大的提升,不會像執行緒切換那樣消耗資源。
子程式,或者稱為函式,在所有語言中都是層級呼叫,比如A呼叫B,B在執行過程中又呼叫了C,C執行完畢返回,B執行完畢返回,最後是A執行完畢。所以子程式呼叫是通過棧實現的,一個執行緒就是執行一個子程式。子程式呼叫總是一個入口,一次返回,呼叫順序是明確的。而協程的呼叫和子程式不同。
協程在子程式內部是可中斷的,然後轉而執行別的子程式,在適當的時候再返回來接著執行。
<span style="color:#000000"><code class="language-py"><span style="color:#c678dd">def</span> <span style="color:#61aeee">A</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">:</span>
<span style="color:#c678dd">print</span> <span style="color:#669900">'1'</span>
<span style="color:#c678dd">print</span> <span style="color:#669900">'2'</span>
<span style="color:#c678dd">print</span> <span style="color:#669900">'3'</span>
<span style="color:#c678dd">def</span> <span style="color:#61aeee">B</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">:</span>
<span style="color:#c678dd">print</span> <span style="color:#669900">'x'</span>
<span style="color:#c678dd">print</span> <span style="color:#669900">'y'</span>
<span style="color:#c678dd">print</span> <span style="color:#669900">'z'</span>
</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
假設由協程執行,在執行A的過程中,可以隨時中斷,去執行B,B也可能在執行過程中中斷再去執行A,結果可能是:1 2 x y 3 z
。
協程的特點在於是一個執行緒執行,那和多執行緒比,協程有何優勢?
-
極高的執行效率:因為子程式切換不是執行緒切換,而是由程式自身控制,因此,沒有執行緒切換的開銷,和多執行緒比,執行緒數量越多,協程的效能優勢就越明顯;
-
不需要多執行緒的鎖機制:因為只有一個執行緒,也不存在同時寫變數衝突,在協程中控制共享資源不加鎖,只需要判斷狀態就好了,所以執行效率比多執行緒高很多。
參考:https://blog.csdn.net/tennysonsky/article/details/46046317
https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/0013868328689835ecd883d910145dfa8227b539725e5ed000
https://www.cnblogs.com/work115/p/5620272.html
https://blog.csdn.net/liu251890347/article/details/38509943
https://www.cnblogs.com/fah936861121/articles/8043187.html
http://blog.chinaunix.net/uid-25601623-id-5095687.html
來源:https://blog.csdn.net/daaikuaichuan/article/details/82951084
相關文章
- 程序、執行緒和協程之間的區別和聯絡執行緒
- 程式和執行緒的區別與聯絡執行緒
- 程式、執行緒、纖程之間的區別?執行緒
- Linux中程式和執行緒的區別與聯絡,建議收藏!Linux執行緒
- 執行緒和程式的區別執行緒
- 程式和執行緒的區別執行緒
- 大話Android多執行緒(一) Thread和Runnable的聯絡和區別Android執行緒thread
- 多執行緒:繼承方式和實現方式的聯絡與區別執行緒繼承
- 一篇讓你明白程式與執行緒之間的區別與聯絡執行緒
- 程式和執行緒的區別(Linux)執行緒Linux
- 作業系統——執行緒與程式的區別與聯絡?什麼是執行緒安全?作業系統執行緒
- 程式和執行緒有什麼區別?(Process and Threads)程式之間和執行緒之間是如何通訊的?執行緒thread
- 「Learning」區別執行緒和程式執行緒
- 對程式、執行緒和協程的理解以及它們的區別執行緒
- 並行和併發的區別與聯絡並行
- java架構-執行緒和程式的區別Java架構執行緒
- Linux中執行緒和程式的區別Linux執行緒
- tcp/ip和http的區別和聯絡TCPHTTP
- orcle pfile和spfile的區別和聯絡
- NET|Ref 和out 的區別和聯絡
- Instruction和Question的區別和聯絡Struct
- 程式、執行緒和協程的概念執行緒
- php中的執行緒、程式和併發區別PHP執行緒
- 作業系統-執行緒和程式的區別作業系統執行緒
- 作業系統_程式和執行緒的區別作業系統執行緒
- 多執行緒和多程式的區別(小結)執行緒
- Oracle中User和Schema的區別和聯絡Oracle
- 詳解CALayer 和 UIView的區別和聯絡UIView
- http、socket、tcp的區別和聯絡?HTTPTCP
- SCADA和PLC的區別聯絡
- Session和Cookie的聯絡與區別SessionCookie
- CGI與Servlet的區別和聯絡Servlet
- Session和Cookie的區別與聯絡SessionCookie
- Java程式和執行緒關係及區別Java執行緒
- 轉:IDOCBAPIRFC區別和聯絡API
- 程序、執行緒、協程的區別執行緒
- java-介面和抽象類的聯絡和區別。Java抽象
- 中斷和異常,陷阱的區別和聯絡