日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

【网络通信与信息安全】之深入解析进程之间的通信方式

發(fā)布時(shí)間:2024/5/28 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【网络通信与信息安全】之深入解析进程之间的通信方式 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、信號(hào) Signal

  • 信號(hào)是 Linux 系統(tǒng)響應(yīng)某些條件而產(chǎn)生的一個(gè)事件,由操作系統(tǒng)事先定義,接收到該信號(hào)的進(jìn)程可以采取自定義的行為,這是一種“訂閱-發(fā)布”的模式。
  • 信號(hào)來(lái)源分為硬件來(lái)源和軟件來(lái)源:
    • 硬件來(lái)源:如按下 CTRL+C、除 0、非法內(nèi)存訪問(wèn)等;
    • 軟件來(lái)源:如 Kill 命令、Alarm Clock 超時(shí),當(dāng) Reader 中止之后又向管道寫數(shù)據(jù)等。
  • 如下所示,Linux 系統(tǒng)上支持的 30 種不同類型的信號(hào):

  • 一般的信號(hào)是都是由一個(gè)錯(cuò)誤產(chǎn)生的。以除 0 為例,在 x86 機(jī)器上 DIV 或 IDIV 指令除數(shù)為 0 時(shí),會(huì)引發(fā) 0 號(hào)中斷,編號(hào) #DE(Divide Error),即所謂除零異常。這是一個(gè)硬件級(jí)中斷,會(huì)導(dǎo)致陷入內(nèi)核,執(zhí)行操作系統(tǒng)預(yù)定義在 IDT 中的中斷處理程序,而操作系統(tǒng)處理這個(gè)異常的方法,就是向進(jìn)程發(fā)送一個(gè)信號(hào) SIGFPE。如果進(jìn)程設(shè)置相應(yīng)的 signal handler,就執(zhí)行進(jìn)程的處理方法。否則,執(zhí)行操作系統(tǒng)的默認(rèn)操作,一般這種信號(hào)的默認(rèn)操作是殺死進(jìn)程。
  • 同理,溢出、非法內(nèi)存訪問(wèn)(越界)、非法指令等也都屬于硬件中斷,由操作系統(tǒng)處理。操作系統(tǒng)會(huì)將這些硬件異常包裝成“信號(hào)”發(fā)送給進(jìn)程。如果進(jìn)程不處理這幾個(gè)異常信號(hào),那么默認(rèn)的行為就是掛掉。
  • 但是,信號(hào)也可以作為進(jìn)程間通信的一種方式,明確地由一個(gè)進(jìn)程發(fā)送給另一個(gè)進(jìn)程。
  • 進(jìn)程如何發(fā)送信號(hào)?
    • 操作系統(tǒng)提供發(fā)送信號(hào)的系統(tǒng)調(diào)用;
    • 該系統(tǒng)調(diào)用會(huì)將信號(hào)放到目標(biāo)進(jìn)程的信號(hào)隊(duì)列中;
    • 如果目標(biāo)進(jìn)程未處于執(zhí)行狀態(tài),則該信號(hào)就由內(nèi)核保存起來(lái),直到該進(jìn)程恢復(fù)執(zhí)行并傳遞給它為止;
    • 如果一個(gè)信號(hào)被進(jìn)程設(shè)置為阻塞,則該信號(hào)的傳遞被延遲,直到其阻塞被取消時(shí)才被傳遞給進(jìn)程。
  • 進(jìn)程如何接收信號(hào)?
    • 每個(gè)進(jìn)程有一個(gè)信號(hào)隊(duì)列,放其它進(jìn)程發(fā)給它、等待它處理的信號(hào);
    • 進(jìn)程在執(zhí)行過(guò)程中的特定時(shí)刻,檢查并處理自己的信號(hào)隊(duì)列,如從系統(tǒng)空間返回到用戶空間之前;
    • 發(fā)送信號(hào)時(shí),必須指明發(fā)送目標(biāo)進(jìn)程的號(hào)碼。一般用在具有親緣關(guān)系的進(jìn)程之間。
  • 用戶進(jìn)程對(duì)信號(hào)的處理過(guò)程有三種:
    • 處理信號(hào):定義信號(hào)處理函數(shù),當(dāng)信號(hào)發(fā)生時(shí),執(zhí)行相應(yīng)的處理函數(shù);
    • 忽略信號(hào):當(dāng)不希望接收到的信號(hào)對(duì)進(jìn)程的執(zhí)行產(chǎn)生影響,而讓進(jìn)程繼續(xù)執(zhí)行時(shí),可以忽略該信號(hào),即不對(duì)信號(hào)進(jìn)程作任何處理;
    • 不處理也不忽略:執(zhí)行默認(rèn)操作,linux 對(duì)每種信號(hào)都規(guī)定了默認(rèn)操作;
  • 有的信號(hào),用戶進(jìn)程是無(wú)法處理也無(wú)法忽略的,比如 SIGSTOP、SIGKILL 等。信號(hào)處理程序是一個(gè)用戶層函數(shù),進(jìn)程可以為某個(gè)信號(hào)指定一個(gè)信號(hào)處理程序,接收到信號(hào)后,進(jìn)程會(huì)跳轉(zhuǎn)執(zhí)行信號(hào)處理程序,執(zhí)行完成后再返回到中斷位置的下一條指令繼續(xù)執(zhí)行:

二、管道 Pipe

  • 管道命令,在 Linux Shell 中經(jīng)常使用,一般使用管道操作符 | 來(lái)表示兩個(gè)命令之間的數(shù)據(jù)通信。比如:
ps -ef | grep java | xargs echo
  • 管道操作符的內(nèi)部實(shí)現(xiàn)其實(shí)就是 Linux 的管道接口,由管道操作符 | 分割的每個(gè)命令是獨(dú)立的進(jìn)程,各個(gè)進(jìn)程的標(biāo)準(zhǔn)輸出 STDOUT,會(huì)作為下一個(gè)進(jìn)程的標(biāo)準(zhǔn)輸入 STDIN。

① 定義

  • 管道是一種半雙工的通信方式,數(shù)據(jù)只能單向流動(dòng),上游進(jìn)程往管道中寫入數(shù)據(jù),下游進(jìn)程從管道中接收數(shù)據(jù)。如果想實(shí)現(xiàn)雙方通信,那么需要建立兩個(gè)管道。
  • 管道適合于傳輸大量信息。管道發(fā)送的內(nèi)容是以字節(jié)為單位的,沒(méi)有格式的字節(jié)流。

② 創(chuàng)建管道

  • 通過(guò) pipe() 系統(tǒng)調(diào)用來(lái)創(chuàng)建并打開(kāi)一個(gè)管道,當(dāng)最后一個(gè)使用它的進(jìn)程關(guān)閉對(duì)他的引用時(shí),pipe 將自動(dòng)撤銷。
  • 通過(guò) pipe() 創(chuàng)建的是匿名管道,只能用于具有親緣關(guān)系的進(jìn)程之間(父子進(jìn)程或兄弟進(jìn)程)。

③ 管道的實(shí)現(xiàn)

  • 管道就是一個(gè)文件,是一種只存在于內(nèi)存中的特殊的文件系統(tǒng)。
  • 在 Linux 中,管道借助文件系統(tǒng)的 File 結(jié)構(gòu)實(shí)現(xiàn),父進(jìn)程使用 File 結(jié)構(gòu)保存向管道寫入數(shù)據(jù)的例程地址,子進(jìn)程保存從管道讀出數(shù)據(jù)的例程地址,這解釋了上文所說(shuō)的:
    • 單向流動(dòng);
    • 只能用于具有親緣關(guān)系的進(jìn)程之間。
  • 管道是由內(nèi)核管理的一個(gè)緩沖區(qū),緩沖區(qū)被設(shè)計(jì)成為環(huán)形的數(shù)據(jù)結(jié)構(gòu),以便管道可以被循環(huán)利用(循環(huán)隊(duì)列)。

④ 管道的同步

  • 管道是一個(gè)具有特定大小的緩沖區(qū):
    • 操作系統(tǒng)會(huì)保證讀寫進(jìn)程的同步;
    • 下游進(jìn)程或者上游進(jìn)程需要等另一方釋放鎖后才能操作管道,管道就相當(dāng)于一個(gè)文件,同一時(shí)刻只能有一個(gè)進(jìn)程訪問(wèn);
    • 當(dāng)管道為空時(shí),下游進(jìn)程讀阻塞;當(dāng)管道滿時(shí),上游進(jìn)程寫阻塞;
    • 管道不再被任何進(jìn)程使用時(shí),自動(dòng)消失。

三、命名管道 FIFO

  • Linux 管道包含匿名管道和命名管道,上文的匿名管道,只能用在親緣進(jìn)程中,管道文件信息保存在內(nèi)存里。
  • 命名管道(FIFO)可用于沒(méi)有親緣的進(jìn)程間,Pipe 和 FIFO 除了建立、打開(kāi)、刪除的方式不同外,二者幾乎一模一樣。
  • 通過(guò) mknode() 系統(tǒng)調(diào)用或者 mkfifo() 函數(shù)建立命名管道,一旦建立,任何有訪問(wèn)權(quán)的進(jìn)程都可以通過(guò)文件名將其打開(kāi)和進(jìn)行讀寫,而不局限于父子進(jìn)程。
  • 建立命名管道時(shí),會(huì)在磁盤中創(chuàng)建一個(gè)索引節(jié)點(diǎn),命名管道的名字就相當(dāng)于索引節(jié)點(diǎn)的文件名。索引節(jié)點(diǎn)設(shè)置了進(jìn)程的訪問(wèn)權(quán)限,但是沒(méi)有數(shù)據(jù)塊。
  • 命名管道實(shí)質(zhì)上也是通過(guò)內(nèi)核緩沖區(qū)來(lái)實(shí)現(xiàn)數(shù)據(jù)傳輸,有訪問(wèn)權(quán)限的進(jìn)程,可以通過(guò)磁盤的索引節(jié)點(diǎn)來(lái)讀寫這塊緩沖區(qū)。
  • 當(dāng)不再被任何進(jìn)程使用時(shí),命名管道在內(nèi)存中釋放,但磁盤節(jié)點(diǎn)仍然存在。

四、信號(hào)量 Semaphore

  • 信號(hào)量是一種特殊的變量,對(duì)它的操作都是原子的,有兩種操作:V(signal())和 P(wait())。
  • V 操作會(huì)增加信號(hào)量 S 的數(shù)值,P 操作會(huì)減少它:
    • V(S):如果有其他進(jìn)程因等待 S 而被掛起,就讓它恢復(fù)運(yùn)行,否則 S 加 1;
    • P(S):如果 S 為 0,則掛起進(jìn)程,否則 S 減 1;
    • P、V 來(lái)自于荷蘭語(yǔ):Probeer (try)、Verhoog (increment)。
  • 如果信號(hào)量是一個(gè)任意的整數(shù),通常被稱為計(jì)數(shù)信號(hào)量(Counting semaphore),或一般信號(hào)量(general semaphore);如果信號(hào)量只有二進(jìn)制的 0 或 1,稱為二進(jìn)制信號(hào)量(binary semaphore)。在 Linux 系統(tǒng)中,二進(jìn)制信號(hào)量又稱互斥鎖(Mutex),信號(hào)量可以用于實(shí)現(xiàn)進(jìn)程或線程的互斥和同步。
  • 信號(hào)量在底層的實(shí)現(xiàn)是通過(guò)硬件提供的原子指令,如 Test And Set、Compare And Swap 等。比如 golang 實(shí)現(xiàn)互斥量就是使用了 Compare And Swap 指令(go)。

五、共享內(nèi)存 Shared Memory

  • 共享內(nèi)存顧名思義,允許兩個(gè)或多個(gè)進(jìn)程共享同一段物理內(nèi)存,不同進(jìn)程可以將同一段共享內(nèi)存映射到自己的地址空間,然后像訪問(wèn)正常內(nèi)存一樣訪問(wèn)它,不同進(jìn)程可以通過(guò)向共享內(nèi)存端讀寫數(shù)據(jù)來(lái)交換信息。
  • 一個(gè)進(jìn)程可以通過(guò)操作系統(tǒng)的系統(tǒng)調(diào)用,創(chuàng)建一塊共享內(nèi)存區(qū);其他進(jìn)程通過(guò)系統(tǒng)調(diào)用把這段內(nèi)存映射到自己的用戶地址空間中;之后各個(gè)進(jìn)程向讀寫正常內(nèi)存一樣,讀寫共享內(nèi)存。共享內(nèi)存區(qū)只會(huì)駐留在創(chuàng)建它的進(jìn)程地址空間內(nèi)。
  • 共享內(nèi)存的優(yōu)點(diǎn)是簡(jiǎn)單且高效,訪問(wèn)共享內(nèi)存區(qū)域和訪問(wèn)進(jìn)程獨(dú)有的內(nèi)存區(qū)域一樣快,原因是不需要系統(tǒng)調(diào)用,不涉及用戶態(tài)到內(nèi)核態(tài)的轉(zhuǎn)換,也不需要對(duì)數(shù)據(jù)不必要的復(fù)制。
  • 比如管道和消息隊(duì)列,需要在內(nèi)核和用戶空間進(jìn)行四次的數(shù)據(jù)拷貝(讀輸入文件、寫到管道;讀管道、寫到輸出文件),而共享內(nèi)存則只拷貝兩次:一次從輸入文件到共享內(nèi)存區(qū),另一次從共享內(nèi)存到輸出文件。


  • 此外,消息傳遞的實(shí)現(xiàn)經(jīng)常采用系統(tǒng)調(diào)用,也就經(jīng)常需要用戶態(tài)和內(nèi)核態(tài)互相轉(zhuǎn)換;而共享內(nèi)存只在建立共享內(nèi)存區(qū)域時(shí)需要系統(tǒng)調(diào)用;一旦建立共享內(nèi)存,所有訪問(wèn)都可作為常規(guī)內(nèi)存訪問(wèn),無(wú)需借助內(nèi)核。
  • 共享內(nèi)存的缺點(diǎn)是存在并發(fā)問(wèn)題,有可能出現(xiàn)多個(gè)進(jìn)程修改同一塊內(nèi)存,因此共享內(nèi)存一般與信號(hào)量結(jié)合使用。
  • Linux 的 2.2.x 內(nèi)核支持多種共享內(nèi)存方式,如 mmap() 系統(tǒng)調(diào)用,Posix 共享內(nèi)存,以及系統(tǒng) V 共享內(nèi)存;
    • mmap() 系統(tǒng)調(diào)用的主要作用是將普通文件映射到進(jìn)程的地址空間,然后可以像訪問(wèn)普通內(nèi)存一樣對(duì)文件進(jìn)行訪問(wèn),不必再調(diào)用 read(),write() 等操作;mmap() 不是專門用來(lái)共享內(nèi)存的,但是多個(gè)進(jìn)程可以通過(guò) mmap() 映射同一個(gè)普通文件,來(lái)實(shí)現(xiàn)共享內(nèi)存。



    • 系統(tǒng) V 則是通過(guò)映射特殊文件系統(tǒng) shm 中的文件實(shí)現(xiàn)進(jìn)程間的共享內(nèi)存,通過(guò) shmget 可以創(chuàng)建或獲得共享內(nèi)存的標(biāo)識(shí)符,取得共享內(nèi)存標(biāo)識(shí)符后,通過(guò) shmat 將這個(gè)內(nèi)存區(qū)映射到本進(jìn)程的虛擬地址空間。
  • 有關(guān) mmap() 系統(tǒng)調(diào)用、系統(tǒng) V 共享內(nèi)存的詳細(xì)介紹,以及兩者的對(duì)比,可以參考:
    • Linux環(huán)境進(jìn)程間通信 - 共享內(nèi)存(上);
    • Linux環(huán)境進(jìn)程間通信 - 共享內(nèi)存(下)。

六、消息隊(duì)列 Message Queue

  • 消息隊(duì)列是一個(gè)消息的鏈表,保存在內(nèi)核中。消息隊(duì)列中的每個(gè)消息都是一個(gè)數(shù)據(jù)塊,具有特定的格式。操作系統(tǒng)中可以存在多個(gè)消息隊(duì)列,每個(gè)消息隊(duì)列有唯一的 key,稱為消息隊(duì)列標(biāo)識(shí)符。
  • 消息隊(duì)列克服了信號(hào)傳遞信息少、管道只能承載無(wú)格式字節(jié)流以及緩沖區(qū)大小受限等缺點(diǎn)。和信號(hào)相比,消息隊(duì)列能夠傳遞更多的信息。與管道相比,消息隊(duì)列提供了有格式的數(shù)據(jù),但消息隊(duì)列仍然有大小限制。
  • 消息隊(duì)列允許一個(gè)或多個(gè)進(jìn)程向它寫入與讀取消息。消息的發(fā)送者和接收者不需要同時(shí)與消息隊(duì)列交互。消息會(huì)保存在隊(duì)列中,直到接收者取回它。也就是說(shuō),消息隊(duì)列是異步的,但這也造成了一個(gè)缺點(diǎn),就是接收者必須輪詢消息隊(duì)列,才能收到最近的消息。
  • 操作系統(tǒng)提供創(chuàng)建消息隊(duì)列、取消息、發(fā)消息等系統(tǒng)調(diào)用。操作系統(tǒng)負(fù)責(zé)讀寫同步:若消息隊(duì)列已滿,則寫消息進(jìn)程排隊(duì)等待;若取消息進(jìn)程沒(méi)有找到需要的消息,則在等待隊(duì)列中尋找。
  • 消息隊(duì)列和管道相比,相同點(diǎn)在于二者都是通過(guò)發(fā)送-接收的方式進(jìn)行通信,并且數(shù)據(jù)都有最大長(zhǎng)度限制。不同點(diǎn)在于消息隊(duì)列的數(shù)據(jù)是有格式的,并且取消息進(jìn)程可以選擇接收特定類型的消息,而不是像管道中那樣默認(rèn)全部接收。

七、套接字 Socket

  • 不同的計(jì)算機(jī)的進(jìn)程之間通過(guò) socket 通信,也可用于同一臺(tái)計(jì)算機(jī)的不同進(jìn)程。
  • 需要通信的進(jìn)程之間首先要各自創(chuàng)建一個(gè) socket,內(nèi)容包括主機(jī)地址與端口號(hào),聲明自己接收來(lái)自某端口地址的數(shù)據(jù)。
  • 進(jìn)程通過(guò) socket 把消息發(fā)送到網(wǎng)絡(luò)層中,網(wǎng)絡(luò)層通過(guò)主機(jī)地址將其發(fā)到目的主機(jī),目的主機(jī)通過(guò)端口號(hào)發(fā)給對(duì)應(yīng)進(jìn)程。
  • 操作系統(tǒng)提供創(chuàng)建 socket、發(fā)送、接收的系統(tǒng)調(diào)用,為每個(gè) socket 設(shè)置發(fā)送緩沖區(qū)、接收緩沖區(qū)。

八、總結(jié)

方式傳輸?shù)男畔⒘渴褂脠?chǎng)景關(guān)鍵詞
信號(hào)少量任何硬件來(lái)源、軟件來(lái)源 / 信號(hào)隊(duì)列
管道大量親緣進(jìn)程間單向流動(dòng) / 內(nèi)核緩沖區(qū) / 循環(huán)隊(duì)列 / 沒(méi)有格式的字節(jié)流 / 操作系統(tǒng)負(fù)責(zé)同步
命名管道大量任何磁盤文件 / 訪問(wèn)權(quán)限 / 無(wú)數(shù)據(jù)塊 / 內(nèi)核緩沖區(qū) / 操作系統(tǒng)負(fù)責(zé)同步
信號(hào)量N任何互斥同步 / 原子性 / P 減 V 增
共享內(nèi)存大量多個(gè)進(jìn)程內(nèi)存映射 / 簡(jiǎn)單快速 / 操作系統(tǒng)不保證同步
消息隊(duì)列比信號(hào)多,但有限制任何有格式 / 按消息類型過(guò)濾 / 操作系統(tǒng)負(fù)責(zé)同步
套接字大量不同主機(jī)的進(jìn)程讀緩存區(qū) / 寫緩沖區(qū) / 操作系統(tǒng)負(fù)責(zé)同步

總結(jié)

以上是生活随笔為你收集整理的【网络通信与信息安全】之深入解析进程之间的通信方式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。