深入探討進程間通信的重要性:理解不同的通信機制(下)

来源:https://www.cnblogs.com/guoxiaoyu/archive/2023/09/01/17665997.html
-Advertisement-
Play Games

本文旨在探討進程間通信的重要性,並介紹了不同的通信機制,如管道、消息隊列、共用記憶體、信號量、信號和套接字。通過理解這些通信機制的特點和應用場景,可以更好地實現進程間的高效數據共用。同時,本文還強調了同步和互斥機制的重要性,以確保數據的一致性和正確性。最後,還介紹了套接字作為一種跨網路和同一主機上進程... ...


前言

在上一篇文章中,我們探討了進程間通信的三種常見機制:管道、消息隊列和共用記憶體。我們瞭解到,這些機制各有其特點和適用場景,可以根據實際需求選擇合適的機制進行進程間通信。然而,進程間通信並不僅限於這三種方式。

在本文中,我們將繼續探索進程間通信的知識點,重點關註信號量、信號和套接字。信號量是一種用於進程同步的機制,它可以用於控制對共用資源的訪問。信號是一種用於進程間通知的機制,可以用於處理非同步事件。而套接字則是一種用於網路通信的介面,它可以實現不同主機之間的進程間通信。

信號量

共用記憶體通信方式雖然提供了高效的數據交換,但也引發了新的問題。如果多個進程同時修改同一個共用記憶體區域,很可能會導致數據衝突。舉個例子,如果兩個進程同時寫入同一個地址,先寫入的進程可能會發現自己的內容被後寫入的進程覆蓋。

在進程間共用資源時,使用信號量可以避免多個進程同時訪問共用資源而導致數據衝突的問題。信號量是一個整型計數器,用來表示資源的可用數量。通過P操作和V操作來控制信號量的值。

  • P操作會將信號量減1,如果結果小於0,則表示資源已被占用,進程需要阻塞等待。如果結果大於等於0,則表示資源仍然可用,進程可以繼續執行。
  • V操作會將信號量加1,如果結果小於等於0,則表示有其他進程正在等待資源,需要喚醒其中一個進程。如果結果大於0,則表示沒有進程在等待資源。

通過使用P操作和V操作,可以實現對共用資源的互斥訪問和同步執行。例如,可以初始化一個信號量為1,使得只有一個進程可以訪問共用資源,從而避免數據錯亂。另外,可以初始化一個信號量為0,使得進程按照特定的順序執行,實現多進程的同步。
接下來,我們先看下互斥訪問,如果要使得兩個進程互斥訪問共用記憶體,我們可以初始化信號量為 1。

image

具體的過程如下:

  • 進程 A 在訪問共用記憶體之前,先執行了 P 操作。由於信號量的初始值為 1,所以進程 A 執行 P 操作後,信號量減為 0,表示共用資源可用,進程 A 可以訪問共用記憶體。
  • 如果此時進程 B 也想訪問共用記憶體,它執行了 P 操作。結果信號量變為 -1,表示臨界資源已被占用,因此進程 B 被阻塞。
  • 直到進程 A 訪問完共用記憶體,才會執行 V 操作,使得信號量恢復為 0。接著,進程 A 喚醒被阻塞的進程 B,使其可以訪問共用記憶體。
  • 最後,進程 B 完成共用記憶體的訪問後,執行 V 操作,將信號量恢復到初始值 1。

將信號量初始化為 1,代表著它是一個互斥信號量。這種設置可以確保在任何時刻只有一個進程可以訪問共用記憶體,從而有效保護了共用記憶體的完整性。有人可能會發現如果多線程都來訪問資源全部阻塞了喚醒誰呢?這不就是我們之前講到的進程調度演算法了嗎?進程阻塞後會進入阻塞隊列,而喚醒哪個進程則由系統的調度演算法決定。

在多進程環境中,每個進程並不一定按照順序執行,它們以各自獨立且不可預測的速度向前推進。然而,在某些情況下,我們希望多個進程能夠密切合作,以實現一個共同的任務。

比如生產者消費者模式,假設進程A負責生產數據,而進程B負責讀取數據,這兩個進程是相互合作、相互依賴的。進程A必須先生產數據,然後進程B才能讀取到數據,因此它們之間存在執行順序。

接下來,我們來討論同步執行。我們可以通過初始化信號量為0來實現。

image

具體過程如下:

  • 如果進程B比進程A先執行,那麼當它執行P操作時,由於信號量的初始值為0,所以信號量會變為-1,表示進程A還沒有生產數據,進程B會被阻塞等待。
  • 接著,當進程A生產完數據後,執行V操作,信號量會變為0,這會喚醒被阻塞在P操作的進程B。
  • 最後,進程B被喚醒後,意味著進程A已經生產了數據,進程B就可以正常讀取數據了。

可以看出,將信號量初始化為0,代表著這是一個同步信號量,它可以保證進程A在進程B之前執行。

信號

信號是一種在異常情況下進行進程間通信的機制,它是一種非同步通信方式,其數據結構一般為一個數字。

在Linux操作系統中,為了響應各種事件,提供了幾十種信號,每個信號代表著不同的含義。可以通過運行"kill -l"命令來查看所有的信號列表。

image

對於在Shell終端中運行的進程,我們可以通過鍵盤輸入某些組合鍵向進程發送信號。例如,按下Ctrl+C會產生SIGINT信號,表示終止該進程;按下Ctrl+Z會產生SIGTSTP信號,表示暫停該進程,但進程並未結束。需要註意的是,Ctrl+Z命令在某些情況下可能會導致記憶體飆升等問題(比如你看一個全量伺服器日誌),因此需要謹慎使用。

如果進程在後臺運行,可以使用kill命令向進程發送信號,但前提是需要知道正在運行的進程的PID(進程ID)。例如,執行"kill -9 ###"命令會向PID為"###"的進程發送SIGKILL信號,用於立即終止該進程。

因此,信號的事件來源主要有硬體來源(如鍵盤的Ctrl+C)和軟體來源(如kill命令)。信號是進程間通信機制中唯一的非同步通信機制,進程需要為信號設置相應的監聽處理程式,當收到特定信號時,執行相應的操作,類似於其他編程語言中的通知機制。

Socket

Socket通信是一種常用的進程間通信機制,可以用於跨網路與不同主機上的進程之間通信,也可以在同一臺主機上的進程之間進行通信。

Socket通信是通過網路協議進行數據傳輸的一種方式。在使用Socket通信時,一個進程可以作為伺服器端創建一個Socket,並指定一個IP地址和埠號來監聽連接請求;另一個進程則可以作為客戶端創建一個Socket,指定伺服器的IP地址和埠號來發起連接。一旦連接建立,伺服器和客戶端就可以通過Socket進行數據的發送和接收。

在同一臺主機上,進程可以使用特殊的IP地址(如本地迴環地址127.0.0.1)和不同的埠號來建立Socket連接,實現進程間的通信。這種方式被稱為本地迴環通信,可以用於進程之間的協作和數據交換。

後期我將詳細講解電腦基礎的網路篇,敬請期待!

總結

IPC 機制 數據抽象 參與者 方向 內核實現
管道 位元組流 兩個進程 單向 通常以 FIFO 的緩衝區來管理數據。
有匿名管道和命名管道兩類主要實現
消息隊列 消息 多進程 單向
雙向
隊列的組織方式。
通過文件的許可權來管理對隊列的訪間
信號量 計數器 多進程 單向
雙向
內核餘護共用計數器。
通過文件的許可權來管理劉計數器的訪問
共用記憶體 記憶體區問 多進程 單向
雙向
內核維護共用的記憶體區可。
通過文件的許可權來管理對共用記憶體的訪間
信號 事件編號 多進程 單向 為線程/進程維護信號等待隊列。
通過用戶了組等的許可權來管理信號的操作
套接字 數據報文 兩個進程 單向
雙向
有基於IP/埠和基於文件路輕的定址方式。
利用網路棧來管理通信

進程間通信是操作系統中的重要概念,它允許不同的進程之間進行數據交換、消息傳遞和協作。在Linux系統中,提供了多種進程間通信的機制,包括管道、消息隊列、共用記憶體、信號量、信號和套接字。每種通信機制都有不同的特點和適用場景。需要根據具體需求選擇合適的方式。進程間通信涉及到資源的共用和競爭,需要合理地使用同步和互斥機制來保證數據的一致性和正確性。同時,進程的喚醒順序也會受到系統的調度演算法的影響。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • # .Net 6/Net Core Vue Element Uniapp前後端分離低代碼快速開發框架 這是一個能提高開發效率的開發框架,全自動生成PC與移動端(uniapp)代碼;支持移動ios/android/h5/微信小程式。 # 一、框架能做什麼 1、前後端分離項目 2、純後端項目 3、移動端 ...
  • ## 前言 在軟體系統中,當創建一個類的實例的過程很昂貴或很複雜,並且我們需要創建多個這樣類的實例時,如果我們用new操作符去創建這樣的類實例,這就會增加創建類的複雜度和創建過程與客戶代碼複雜的耦合度。如果採用工廠模式來創建這樣的實例對象的話,隨著產品類的不斷增加,導致子類的數量不斷增多,也導致了相 ...
  • # 高併發解決方法-LVS、LVS-NAT、LVS-DR ## 前言: 集群功能分類: 1.LB Load Balancing,負載均衡(增加處理能力),有一定高可用能力,但不是高可用集群,是以提高服務的**併發處理**能力為根本著重點。**LVS** 2.HA High Availability ...
  • 哈嘍大家好,我是鹹魚 在《[一臺伺服器上部署 Redis 偽集群》](https://mp.weixin.qq.com/s?__biz=MzkzNzI1MzE2Mw==&mid=2247486439&idx=1&sn=0b10317397ef3259dd98d493915dd706&chksm=c2 ...
  • 1.操作系統的多進程圖像 操作系統main函數中最後 if(!fork()) {init();} ,也就是main函數最後創建了第1個進程,init執行了shell(Windows)桌面。 操作系統管理和組織進程都使用PCB(Process Control Block),不同的程式的PCB放在不同的 ...
  • **背景:** 項目現場有一個伺服器需要作國家二級等保整改,有一個高風險選項是需要安裝防惡意代碼軟體,所以就考慮安裝clamAV來實現。現場使用cnetos7伺服器,且無外網,只能離線安裝。 如果有外網直接執行以下命令就行了。 ``` # ubuntu sudo apt install clamav ...
  • iostat 是一個常用的工具,可以提供關於磁碟活動的詳細統計信息。通過運行命令 iostat -x 1 可以實時監測磁碟的使用情況,其中 %util 列就表示磁碟的繁忙度,數值越高表示磁碟越繁忙。 ...
  • **內核版本5.4** 在使用spi匯流排接上了一個小網卡,實現了我們開發板對網路的訪問之後,我還想接一個小的[spi屏幕 1.44寸款](https://item.taobao.com/item.htm?spm=a1z09.2.0.0.731e2e8dAkrB01&id=571409957622&_ ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...