進程和線程的對比和區別


一、什么是進程,什么是線程?

1.1 進程

  • 進程中包括有多個線程,進程與進程之間是相對比較獨立的。
  • 進程中有一個邏輯內存,每個進程都會有分配到一個獨立的內存空間,還分配了一個文件/網絡句柄,
  • 句柄類似一個標識符,所有的進程所或多或少都有一定的句柄數的引用,句柄實際上是一個指針,指向一塊包含具體信息數據的內存,所以句柄是當你要訪問該進程時取得的,使用完必須釋放。(打個比方,我要使用redis需要打開6379端口,這個時候需要訪問句柄,獲取到內存地址去訪問獲取對應的資源來執行該進程)
  • 一個進程可以擁有多個句柄數目,但是只有一個進程ID
  • 進程不同時刻所引用的句柄數目是不一定的


     
    進程結構

1.2 線程

  • 線程中有一個棧內存(很多人把它稱為堆棧),主要用來存儲局部變量資源或者內存地址
  • 還有一個PC塊,主要是存儲下一條執行指令的地址,PC是指向一塊共同的內存(進程里面的被系統分配到的邏輯內存)。
  • TCS :ThreadLocalStorage 主要存儲線程自己定義的變量,不想和其他線程進行共享,理解為線程的私有變量。
  • 線程共享進程的資源主要有:進程代碼塊、進程的全局和靜態變量、進程打開的文件描述符、信號的處理器、進程當前的目錄、進程ID、進程組ID

二、進程和線程的區別

  • 進程是程序資源分配的最小單位,線程是程序執行的最小單位。
  • 進程有自己的內存地址空間,線程包含在進程的地址空間中。
  • 相對於進程與進程之間線程之間通信方式比較方便,線程能共享進程分配到的邏輯內存的資源。也就是說,同一進程下的線程共享全局變量、靜態變量等數據,具體共享的內容1.2中介紹線程已經說明。
  • 進程的分配開銷比線程大,但是進程的健壯性比線程高,因為進程間不會互相影響,線程一個掛掉了可能會造成進程崩潰。
  • 也可以這么說,線程是程序執行的單位,進程只是存放線程的容器,容器會提供線程執行的資源。

三、進程和進程之間的通信方式

因為進程與進程之間是相互獨立的,所以關於進程之間的通信數據共享復雜,需要用IPC;數據是分開的,同步簡單,但是占用內存多,切換復雜,CPU利用率低。

IPC的方式通常有:管道(包括無名管道和命名管道)、消息隊列、信號量、共享存儲、Socket、Streams等

3.1 管道

管道,通常指無名管道,是 UNIX 系統IPC最古老的形式。

3.1.1 管道的特點

  • 它是半雙工的(即數據只能在一個方向上流動),具有固定的讀端和寫端。
  • 它只能用於具有親緣關系的進程之間的通信(也是父子進程或者兄弟進程之間)。
  • 它可以看成是一種特殊的文件,對於它的讀寫也可以使用普通的read、write 等函數。但是它不是普通的文件,並不屬於其他任何文件系統,並且只存在於內存中

3.1.2 原型結構

當一個管道建立時,它會創建兩個文件描述符:fd[0]為讀而打開,fd[1]為寫而打開。如下圖:要關閉管道只需將這兩個文件描述符關閉即可。


 
管道原型

3.13 示例

單個進程中的管道幾乎沒有任何用處。所以,通常調用 pipe 的進程接着調用 fork,這樣就創建了父進程與子進程之間的 IPC 通道。如下圖所示:


 
示例

若要數據流從父進程流向子進程,則關閉父進程的讀端(fd[0])與子進程的寫端(fd[1]);反之,則可以使數據流從子進程流向父進程。

3.2 有名管道FIFO

FIFO,也稱為命名管道,它是一種文件類型。

3.2.1 特點

  • 有名管道也是半雙工的通信方式,但是它允許無親緣關系進程間的通信。
  • FIFO可以在無關的進程之間交換數據,與無名管道不同。
  • FIFO有路徑名與之相關聯,它以一種特殊設備文件形式存在於文件系統中

3.2.2 介紹

FIFO的通信方式類似於在進程中使用文件來傳輸數據,只不過FIFO類型文件同時具有管道的特性。在數據讀出時,FIFO管道中同時清除數據,並且“先進先出”。

3.3 消息隊列

消息隊列,是消息的鏈接表,存放在內核中。一個消息隊列由一個標識符(即隊列ID)來標識。用戶進程可以向消息隊列添加消息,也可以向消息隊列讀取消息。

3.3.1 特點

  • 消息隊列是面向記錄的,其中的消息具有特定的格式以及特定的優先級
  • 消息隊列獨立於發送與接收進程。進程終止時,消息隊列及其內容並不會被刪除,所以另一個進程讀寫的時候要判斷前進程是否已經讀完數據。
  • 消息隊列可以實現消息的隨機查詢,消息不一定要以先進先出的次序讀取,也可以按消息的指定類型讀取

3.4 信號量

信號量(semaphore)與已經介紹過的 IPC 結構不同,它是一個計數器。信號量用於實現進程間的互斥與同步,而不是用於存儲進程間通信數據。

3.4.1 特點

  • 信號量用於進程間同步,若要在進程間傳遞數據需要結合共享內存
  • 信號量基於操作系統的 PV 操作,程序對信號量的操作都是原子操作
  • 每次對信號量的 PV 操作不僅限於對信號量值加 1 或減 1,而且可以加減任意正整數
  • 支持信號量組。

3.5 共享內存

共享內存(Shared Memory),指兩個或多個進程共享一個給定的存儲區。

3.5.1 特點

  • 共享內存是最快的一種 IPC,因為進程是直接對內存進行存取。
  • 因為多個進程可以同時操作,所以需要進行同步。
  • 信號量+共享內存通常結合在一起使用,信號量用來同步對共享內存的訪問。

3.6 五種通信方式的對比

1.管道:速度慢,容量有限,只有父子進程能通訊
2.FIFO:任何進程間都能通訊,但速度慢
3.消息隊列:容量受到系統限制,且要注意第一次讀的時候,要考慮上一次沒有讀完數據的問題
4.信號量:不能傳遞復雜消息,只能用來同步
5.共享內存區:能夠很容易控制容量,速度快,但要保持同步,比如一個進程在寫的時候,另一個進程要注意讀寫的問題,相當於線程中的線程安全,當然,共享內存區同樣可以用作線程間通訊,不過沒這個必要,線程間本來就已經共享了同一進程內的一塊內存。

四、線程與線程之間的通信(多線程)

4.1 同步

4.2 wait和notify/notifyAll機制

4.3 while輪詢的方式

4.4 管道通信

4.5 Semaphore 信號量



作者:淺藍色的麻吉
鏈接:https://www.jianshu.com/p/00bd894ff86c
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM