跳至主要内容

[CS] 進程與線程的概念整理(process and thread)

keywords: process, thread, concurrent, parallel

此篇為各筆記之整理,非原創內容,資料來源可見下方連結與文後參考資料:

「當程式碼要執行時,編譯好的程式碼會送到 OS 去處理,OS 會將不同的事務分派到不同的記憶體空間(也就是 process 的 heap 和 stack 所在)、program counter、PID (process id ) 等等。

一個 process 至少有一個 thread,稱作 primary thread,而這個 primary thread 可以建立更多其他的 thread,當這個 primary thread 執行結束後,這個 process 就會跟著結束,也就是說,process 是在記憶體中執行的程式」- Achieving concurrency in Go

process(進程、程序、處理序、行程)

  • 每個應用程式至少都是一個 process
  • 對作業系統來說,它是資源分配的最小單位
  • 『 上下文切換 ( context switch ) 』,它是由作業系統的核心 ( kernel ) 來處理這工作
  • Each process has its own memory address space. One process cannot pollute the memory space of another process. This implies that if one process fails, the others keep functioning.

多進程(multi-processing)

  • 指的是在單一作業系統中使用兩個以上的 CPU 處理器(processor)來在同一時間執行多個進程
  • 邏輯 cpu = 物理 cpu 個數 X cpu 核數 ( 先別管超線程 )。然後有幾個邏輯 cpu 就代表『 同一個 』時間可以開幾條生產線來工作

thread(線程、執行緒)

  • A process has at least one thread called the "main thread". Threads within a process share a memory address space. Using the shared memory space (heap) allows threads to communicate with one another.
  • One malfunctioning thread could bring down the entire process.
  • 對作業系統來說,它是最小的操作單位,也是 cpu 的最小執行單位,且它包含在 process 中。
  • thread 是程式碼片段實際的執行者,它可以存取 process, OS resources 等等提供的記憶體。
    • 在執行程式碼時,thread 會將變數保存在記憶體空間中,稱作 stack。stack 會在程式 runtime 執行,通常有固定容量(1 - 2MB),但在 thread 中的 stack 只有它自己可以使用,並不能和其它 thread 共享(可以想成變數有 scope 的概念?)
    • heap 則是 process 中的另一個屬性,它可以被該 process 中的任何 thread 取用,也就是 heap 是共享的記憶體空間
  • 作業系統可以分配 cpu 直接給 thread 來進行工作,然後在同一個 process 中的 thread 都可以共享 process 的記憶體空間
  • process 是 OS 分配資源的最小單位,而 thread 則是作業系統能夠進行運算排程的最小單位,也就是說實際執行任務的並不是進程,而是進程中的線程。
  • 一個進程有可能有多個線程,其中多個線程可以共用進程的系統資源,可以把進程比喻為一個工廠,線程則是工廠裡面的產線,負責任務的實際執行

多執行緒(multi-threading)

  • 在一個 process 中可以有多個 thread 以 concurrently(並行)或 parallelism(平行)的方式運作
  • 當一個 thread 有 memory leak 的情況產生時,它可能會耗盡其它 thread 的資源,進而導致整個 process 停滯
  • 由於 multi-threading 的情況下,不同 thead 會共用記憶體資源,因此它們彼此之間需要合作,在同一時間點只能有一個 thread 去存取某個資料,以特定順序的方式執行 multiple threads 稱作「scheduling」
🔥 重點
  1. thread 和 process 很重要的差異是,同一 process 中的不同 thread 其記憶體資源是可以共享的。
  2. concurrently 並不是真的「同時」運作,而是透過在 context 間快速切換(context switching)來看起來同時,但實際上一次還是只做一個;parallel 才是真的「同時」處理多個事務。

coroutine(協程、協同程序)

  • Even though context switching between threads is faster than between process, it is still excessively costly. Fibers or coroutines are hence mechanisms for this.
  • 協程想要將異步非阻塞的 I/O 操作變成同步的
  • 在 Nodejs 中使用的 async/await 就是協程
  • 協程是相較於線程更小的執行單位,但它是純應用端的執行單位,作業系統並不知道它,它與線程一樣有自己的記憶體空間
  • process 是作業系統的最小資源管理單位,thread 是作業系統的最小操作單位,coroutine 是一個比一個 thread 更小的操作單位,但是它是透過應用層被操作,而不是被作業系統所操作
  • Coroutine 無法提升性能,只是讓原本非阻塞的操作能夠被同步執行

進(線)程池(process/thread pool)

  • 進(線)程池:預先建立好,帶有一堆進程的隊列,有需要時就進去拿,而不用重新建立,以此增加效能並減少執行時的延遲。
  • 之所以要開多個 process 或 thread 常是因為要「並行運算」或做 I/o 處理
  • 透過進程池可以幫助我們管理 process,並減少建立和結束 process 的資源消耗
  • 同一個時間下,一個進程只會被分配到一顆 CPU 工作,假設進程池設 4 個,但只有一個 CPU,那基本上同一時間內最多只會有一個進程在工作

連線池(connection pool)

  • 連線池:建立一個隊列來存放許多的連線
  • 連線池可以減少資源消耗和時間處理,並且保護連線池連線的對象
  • i/o 處理目前主要有兩種模式
    • 多進(線)程模式:每一個 i/o 都要開一個 thread,若 thread pool 大小設為 20,表示同一時間最多只能有 20 個 thread,也就是同一個時間最多只能發出 20 個請求,這時候即使連線池提供 100 的大小也用不到
    • reactor 非阻塞 i/o 模式

mysql 是一個請求就會開一個 thread 來處理

參考資料