【恐龍】理解 Process & Thread

整理網路上對於 Process 和 Thread 的解釋

EREN
erens-tech-book
12 min readAug 21, 2018

--

Program (程式)

Program 意旨軟體工程師所寫的程式碼 (code) 的集合,也就是還尚未 load 進記憶體的程式碼,存放在次級儲存裝置 (Secondary storage)。也可以想像成是設計一座工廠的藍圖就是 Program。

總結

  • 一個 Program 可以執行多次,同時產生多個 Process。

Process (行程,亦可稱作處理程序、進程)

Process 意旨已經執行並且 load 到記憶體中的 Program,行程中的每一行程式碼隨時都有可能被 CPU 執行。在實際生活中,點開應用程式就是將 Program 活化成 Process,我們在活動監控器 (mac) 或 jobs (linux) 中看到 PID,也就是執行中的 Process ID。Program 是工廠藍圖,Process 就是照著設計藍圖所完成的實體工廠。

每一個 Process 又由下面兩項組成:

  • 一個 Memory Space。相當於 Object 的 variable,不同 Process 的 Memory Space 也不同,彼此看不到對方的 Memory Space。
  • 一個以上的 Thread。

多工作業系統 (Multitasking Operating System) 可以同時執行數個 Process,然而一個 CPU 一次只能執行一個 Process (因此才有現在的多核處理器),CPU 的總量又總是少於 Process 的運行總量,且 Process 會佔用記憶體。因此如何排程 (Scheduling)、如何有效管理記憶體 (Memory Management) 是作業系統 (OS) 所關注的事。另外,每個 Process 所需的記憶體總合,也可能大於實體記憶體,因此需要用次級儲存裝置充當虛擬記憶體 (Virtual Memory),因此如何對虛擬記憶體做到最小的依賴,盡可能避免 Page Fault,並防止 Thrashing 的發生以達到最佳化,也是作業系統 (OS) 需要處理的學問。

總結

  • Process 是電腦中已執行 Program 的實體,每一個 Process 互相獨立。
  • Process 需要一些資源才能完成工作,如 CPU、記憶體、檔案以及 I/O 裝置。
  • Process 不是基本執行單位,而是 Thread (執行緒) 的容器。
  • 每個 Process 由一個 Memory Space 和一個以上的 Thread 所組成。

Thread (執行緒,亦可稱作線程)

前面有提到 Process 是 Thread 的容器,在同一個 Process 中會有很多個 Thread,每一個 Thread 負責某一項功能。以聊天室 Process 為例,可以同時接受對方傳來的訊息以及發送自己的訊息給對方,就是同個 Process 中不同 Thread 的功勞。Thread 就是實體工廠內的工人,確保工廠的每項功能,並且共享工廠內的每一項資源。

每一個 Thread 又由下面兩項組成:

  • Stack:紀錄從某個起始點開始 (例如main),到目前為止所有函數的呼叫路徑,以及在這些呼叫路徑上所用到的區域變數。
  • 紀錄 CPU 內部的暫存器 (如 Program Counter, Stack Pointer, Program Status Word 等) 的狀態。

在多執行緒中 (Multithreading),兩個執行緒若同時存取或改變全域變數 (Global Variable),可能會發生同步 (Synchronization) 問題。若執行緒之間互搶資源,則可能產生死結 (Deadlock),如何避免 (Prevent) 或預防 (Avoid) 上述兩種情況的發生,仍是作業系統 (OS) 所關注的。

  • 死結條件 (四個皆滿足):
  1. 這個資源不能同時給兩個人用。
  2. 有一個人拿了一個資源,又想拿別人的資源。
  3. 如果一個人占用資源很久,仍不能趕他走。
  4. A 等 B,B 等 C,C 等 D,D 又等 A,等成一圈。

總結

  • Thread 是系統處理工作的基本單元。
  • 一個 Process 會同時存在多個 Thread。
  • 一個 Process 底下的 Thread 共享資源,如記憶體、全域變數 (Global Variable) 等,不同的 Process 則否。
  • 同一個 Process 內的 Thread 使用相同的 Memory Space,但這些 Thread 各自擁有其 Stack。換句話說,Thread 能透過 reference 存取到相同的 Object,但是 local variable 各自獨立。
  • 作業系統 (OS) 會根據 Thread 的優先權以及使用過的 CPU 時間,在不同的 Thread 作切換,讓各個 Thread 都有執行的機會。

Multi-threading vs Multi-processing

一間工廠 (Process) 擁有資源與設備但需要由員工 (Thread) 去操作才能生產產品。所以要做出一件成品,工廠內至少要有一位員工在做事。以電腦分時運作架構來看,不同的行程就像是不同的工廠,而執行緒則像是一位派遣員工一樣由作業系統負責調度他在什麼時間該去那家工廠上班。

如果電腦擁有多個處理核心,即代表系統可以同時調用的員工數目增加,所謂人多好辦事,如此一來系統在為執行緒安排工作時就有兩種策略:

  1. 第一種策略是在同一時間內為各家工廠都分配一個員工去作事,這種方式稱作多行程 (Multi-processing) 平行執行。跟單一行程處理比起來,其優點在於可以在相同的時間內完成較多的工作
  2. 另一種策略是在同一時間內把所有員工都派到同一家工廠去工作,此法稱做多執行緒 (Multi-threading) 平行執行。相較於單一執行緒處理方式,它有機會讓相同的工作在比較短的時間內完成

Multi-processing (多行程)

指多個 Process 在執行,彼此有各自的資料空間,若有資料需要共用,必須採用特別的方法來傳遞 (視 OS 而定)。

由於每個 Process 都需要一些資源來工作,所以 Multi-process 會比 Multi-thread 更消耗資源 (Google Chrome 採用這種設計,因此會消耗不少記憶體)。

Multi-threading (多執行緒)

指一個 Process 裡有多個執行緒在執行,彼此共用相同的資料空間。

多執行緒工作的其中一項特點就是隸屬在同一行程下的所有執行緒會分享該行程的所有資源,此外各執行緒彼此間也可以擁有自己私有的資源而不與其它同一行程內的執行緒共用。

這就像是工廠內的公共設備是所有員工可以自由使用一樣,但每個員工也都會有自己的工作空間與置物櫃可以擺放自己私人的物品,其他員工不能隨意侵犯他人的私有領域。

總結

  • 擁有多處理核心的電腦系統可以同時平行處理多項行程或將單一行程平行處理。
  • 一個行程被執行時至少要有一個執行緒,但也可同時擁有多個執行緒來進行處理。
  • 行程間的資源是彼此獨立不共用的,但是在同一行程下的所有執行緒分享該行程的所有資源。
  • 同一行程下的執行緒之間也能夠擁有彼此獨立的資源。

Python 3: multiprocessing vs multithreading

Different concurrent designs enable different ways to parallelize.

  • 並發性 (Concurrency) 是指多個任務可以在重疊的時間段內開始、執行及完成。並發事件不一定要在同一時刻執行。例如,在單核機器上進行多任務處理。

Concurrency is when two tasks can start, run, and complete in overlapping time periods.

  • 平行性 (Parallelism) 是指多個任務同時執行 (executed simultaneously),具有並發的意義,但是並發未必平行。

threading

Python 中所使用的執行緒是什麼?

  • 在 GUI 應用程式中保持 UI 執行緒響應
  • IO 任務 (網路或檔案系統)

Don’t use threads to improve performance of CPU bound tasks. You will always end up with worse performance. don’t use threads to improve performance of CPU bound tasks. You will always end up with worse performance.

因此不要使用執行緒來改善綁定 CPU 的任務,你很可能會遇到更糟糕的效能。

由於 CPython 的 GIL (Global Interpreter Lock) 限制,可能會造成大部分的 Python 程式無法以多執行緒發揮多核心 CPU 的效能,若遇到這樣的狀況,可以考慮改用多行程 (multiprocessing) 的方式來設計程式。

Understanding the Python GIL — David Beazley

multiprocessing

對於綁定 CPU 的任務可以改用 multiprocessing 模組。

下面是一些 multiprocessing 模組的一些典型任務:

  • 使用 Process 或 Pool 物件平行化計算密集型的任務
  • 使用 dummy 模組,以 Pool 搭配執行緒,平行化 I/O 密集型的任務
  • 使用 queue 模組分攤序列化的工作

queue

參考資料

--

--

EREN
erens-tech-book

“I’m quite illiterate, but I read a lot. “ — J.D.Salinger, The Catcher in the Rye