【Linux】進程間通信——進程間通信的介紹和分類、管道、匿名管道、命名管道、匿名管道與命名管道的區別

文章目錄

  • 進程間通信
    • 1.進程間通信的介紹
      • 1.1目的和發展
    • 2.進程間通信分類
    • 3.管道
      • 3.1匿名管道
        • 3.1.1匿名管道的原理(文件角度)
        • 3.1.2匿名管道的原理(內核角度)
        • 3.1.3管道讀寫規則
        • 3.1.4管道特點
      • 3.2命名管道
        • 3.2.1創建命名管道
        • 3.2.2命名管道的打開規則
    • 4.命名管道實現server&client通信

進程間通信

1.進程間通信的介紹

??進程間通信(IPC,Interprocess communication)是一組編程接口,讓程序員能夠協調不同的進程,使之能在一個操作系統里同時運行,并相互傳遞、交換信息。這使得一個程序能夠在同一時間里處理許多用戶的要求。因為即使只有一個用戶發出要求,也可能導致一個操作系統中多個進程的產生。進程間通信可以發生在同一臺機器上的不同進程間,也可以發生在不同機器上的進程間。
??

1.1目的和發展

??目的:

??(1)數據傳輸:一個進程需要將它的數據發送給另一個進程。

??(2)資源共享:多個進程之間共享同樣的資源。

??(3)通知事件:一個進程需要向另一個或一組進程發送消息,通知它(它們)發生了某種事件(如進程終止時要通知父進程)。

??(4)進程控制:有些進程希望完全控制另一個進程的執行(如Debug進程),此時控制進程希望能夠攔截另一個進程的所有陷入和異常,并能夠及時知道它的狀態改變。
??
??發展:

??管道 -> System V進程間通信 -> POSIX進程間通信。
??

2.進程間通信分類

??管道:匿名管道、命名管道

??System V IPC:System V 消息隊列、System V 共享內存、System V 信號量

??POSIX IPC:消息隊列、共享內存、信號量、互斥量、條件變量、讀寫鎖
??

3.管道

??管道是Unix中最古老的進程間通信的形式。我們把從一個進程連接到另一個進程的一個數據流稱為一個“管道”。
在這里插入圖片描述
??

3.1匿名管道

??匿名管道的原理:

??匿名管道的原理是使用pipe函數創建管道,并在父進程中得到兩個文件描述符,一個用于從管道讀數據,另一個用于向管道寫數據。 子進程在創建時會自動繼承這兩個文件描述符,從而可以實現父子進程間的數據交換。

#include <unistd.h>//功能:創建一無名管道//原型
int pipe(int fd[2]);//參數
//fd:文件描述符數組,其中fd[0]表示讀端, fd[1]表示寫端
//返回值:成功返回0,失敗返回錯誤代碼

在這里插入圖片描述

//例子:從鍵盤讀取數據,寫入管道,讀取管道,寫到屏幕
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main( void )
{int fds[2];char buf[100];int len;if ( pipe(fds) == -1 )perror("make pipe"),exit(1);// read from stdinwhile ( fgets(buf, 100, stdin) ) {len = strlen(buf);// write into pipeif ( write(fds[1], buf, len) != len ){perror("write to pipe");break;}memset(buf, 0x00, sizeof(buf));// read from pipeif ( (len=read(fds[0], buf, 100)) == -1 ) {perror("read from pipe");break;}// write to stdoutif ( write(1, buf, len) != len ) {perror("write to stdout");break;}}
}

??

3.1.1匿名管道的原理(文件角度)

??匿名管道的原理從文件角度來說,是利用內存中共享的一段緩沖區,以文件的方式對緩沖區實現。但因為該文件只存在于內存中,沒有唯一命名,所以稱為匿名管道。

??具體來說,父進程創建管道文件描述符,然后通過fork創建子進程。子進程繼承了父進程的文件描述符,這樣父子進程就可以通過這個文件描述符進行通信。 由于管道是半雙工方式,數據傳輸的方向是單向的,所以如果需要進行雙向通信,需要創建兩個管道。

在這里插入圖片描述

在這里插入圖片描述

??

3.1.2匿名管道的原理(內核角度)

??從內核角度來說,匿名管道的原理是利用內核緩沖區作為偽文件,這個緩沖區由讀端和寫端兩部分組成,對應兩個文件描述符。數據從寫端流入,從讀端流出。

??匿名管道的內部實現方式是隊列,而且是環形隊列。這種隊列的特性是先進先出,即一端入隊,另一端出隊,即只能從一端寫入,另一端讀出。緩沖區的大小默認是4k字節,但會根據實際情況做適當調整。

??由于用隊列實現,數據只能讀取一次,不能重復讀取。另外,匿名管道是半雙工方式,數據傳輸的方向是單向的。此外,匿名管道只適用于有血緣關系的進程,如父子進程、兄弟進程等。

在這里插入圖片描述

這也符合了Linux的一切皆文件的思想

??
??父進程tast_struct中有指向file_struct的指針 *file,其中files_struct是一個struct file *fd_array[],這個array的數組中指向了各種的文件。同時創建子進程,子進程是父進程的一份拷貝,所以此時父進程指向的文件,子進程也同樣會指向該文件,進程間通信的前提完成:讓不同的文件看到同一份資源。

??
在這里插入圖片描述
??

??接著,我們可以進行不同進程間的通信了,如果我們想要先讓子進程寫入,父進程讀取。則我們可以在父進程和子進程所指的同一個文件中,進行不同的操作:讓子進程在文件緩沖區中寫入數據,讓父進程在同樣的文件緩沖區中讀取數據。即可完成通過使用管道的通信操作(所以管道也是文件)。

在這里插入圖片描述
??

3.1.3管道讀寫規則

??(1)當沒有數據可讀時
??O_NONBLOCK disable:read調用阻塞,即進程暫停執行,一直等到有數據來到為止。
??O_NONBLOCK enable:read調用返回-1,errno值為EAGAIN。

??(2)當管道滿的時候
??O_NONBLOCK disable: write調用阻塞,直到有進程讀走數據。
??O_NONBLOCK enable:調用返回-1,errno值為EAGAIN。

??(3)如果所有管道寫端對應的文件描述符被關閉, 則read返回0。

??(4)如果所有管道讀端對應的文件描述符被關閉, 則write操作會產生信號SIGPIPE,進而可能導致write進程退出。

??(5)當要寫入的數據量不大于PIPE_BUF時,linux將保證寫入的原子性。

??(6)當要寫入的數據量大于PIPE_BUF時,linux將不再保證寫入的原子性。

??

3.1.4管道特點

??(1)只能用于具有共同祖先的進程(具有親緣關系的進程)之間進行通信; 通常,一個管道由一個進程創建,然后該進程調用fork,此后父、子進程之間就可應用該管道。

??(2)管道提供流式服務

??(3)一般而言,進程退出,管道釋放,所以管道的生命周期隨進程

??(4)一般而言,內核會對管道操作進行同步與互斥

??(5)管道是半雙工的,數據只能向一個方向流動; 需要雙方通信時,需要建立起兩個管道。

在這里插入圖片描述
??

3.2命名管道

??命名管道的介紹:

??Linux命名管道是一種特殊的文件類型,它允許不具有親緣關系的進程之間進行通信。命名管道存在于文件系統中,但同時具有管道的優點,可以用于進程間通信。進程通過操作命名管道文件進行數據交換。

??命名管道的創建可以使用命令行工具(如mkfifo命令)或者在編程語言中的調用系統調用接口(如mkfifo函數)來創建。 創建好命名管道之后,可以使用open()和read/write()函數來讀取和寫入數據。

??在數據傳輸方面,命名管道的數據傳輸不會寫入磁盤,而是在內存中進行傳遞。命名管道允許多個進程通過使用相同的管道名稱進行通信,而不僅僅是兩個進程之間的通信。與普通管道一樣,命名管道中的數據也是臨時存儲在內存中的。

??

3.2.1創建命名管道

??命名管道可以從命令行上創建:

$ mkfifo filename

??
??命名管道也可以從程序里創建,相關函數有:

int mkfifo(const char *filename,mode_t mode);

??
??創建命名管道:

int main(int argc, char *argv[])
{mkfifo("p2", 0644);return 0;
}

??
??匿名管道與命名管道的區別:

??(1)匿名管道由pipe函數創建并打開。

??(2)命名管道由mkfifo函數創建,打開用open。

??(3)FIFO(命名管道)與pipe(匿名管道)之間唯一的區別在它們創建與打開的方式不同,一但這些工作完成之后,它們具有相同的語義。

??

3.2.2命名管道的打開規則

??(1)如果當前打開操作是為讀而打開FIFO時
??O_NONBLOCK disable:阻塞直到有相應進程為寫而打開該FIFO。
??O_NONBLOCK enable:立刻返回成功。

??(2)如果當前打開操作是為寫而打開FIFO時
??O_NONBLOCK disable:阻塞直到有相應進程為讀而打開該FIFO。
??O_NONBLOCK enable:立刻返回失敗,錯誤碼為ENXIO。

??

4.命名管道實現server&client通信

測試實現:

在這里插入圖片描述
??

comm.hpp

#pragma once#include<iostream>
#include<sys/types.h>
#include<sys/stat.h>
#include<cerrno>
#include<string>
#include <unistd.h>
#include <fcntl.h>#define FIFO_FILE "./myfifo"
#define MODE 0664enum{FIFO_CREATE_ERR=1,FIFO_DELETE_ERR=2,FIFO_OPEN_ERR=3
};

??
Makefile

.PHONY:all
all:server client
server:server.ccg++ -o $@ $^ -std=c++11
client:client.ccg++ -o $@ $^ -std=c++11
.PHONY:clean
clean:rm -f client server myfifo

??
server.cc

//#include<iostream>
#include"comm.hpp"using namespace std;//管理管道文件
int main()
{//創建信道int n=mkfifo(FIFO_FILE,MODE);if(n==-1){perror("mkfifo");exit(FIFO_CREATE_ERR);}//sleep(5);//打開信道int fd=open(FIFO_FILE,O_RDONLY);if(fd<0){perror("open");exit(FIFO_OPEN_ERR);}cout<<"server open file done"<<endl;//開始信道while(true){char buffer[1024]={0};int x=read(fd,buffer,sizeof(buffer));if(x>0){buffer[x]=0;cout<<"client say#"<<buffer<<endl;}else if(x==0){cout<<"clinet quit,me too!\n"<<endl;break;} else break;}close(fd);int m=unlink(FIFO_FILE);if(m==-1){perror("unlink");exit(FIFO_DELETE_ERR);}return 0;
}

??
client.cc

#include<iostream>
#include"comm.hpp"using namespace std;int main()
{int fd=open(FIFO_FILE,O_WRONLY);if(fd<0){perror("open");exit(FIFO_OPEN_ERR);}string line;while(true){cout<<"Please Enter@";//cin>>line;getline(cin,line);write(fd,line.c_str(),line.size());}close(fd);return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/162875.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/162875.shtml
英文地址,請注明出處:http://en.pswp.cn/news/162875.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

PTA-列出所有祖先結點

對于給定的二叉樹&#xff0c;本題要求你按從上到下順序輸出指定結點的所有祖先結點。 輸入格式: 首先第一行給出一個正整數 N&#xff08;≤10&#xff09;&#xff0c;為樹中結點總數。樹中的結點從 0 到 N?1 編號。 隨后 N 行&#xff0c;每行給出一個對應結點左右孩子的…

談思生物醫療直播 | 利用類器官模型研究肺的發育與穩態

類器官是一種三維細胞培養物&#xff0c;其在細胞類型&#xff0c;空間結構及生理功能上能夠模擬對應器官&#xff0c;從而提供一個高度生理相關的系統。自2009年小腸類器官首次建立至今&#xff0c;類器官研究已經延伸到多個組織系統&#xff0c;并成為當下生命科學領域最熱門…

element plus 使用細節

菜鳥一直在糾結這個寫不寫&#xff0c;因為不難&#xff0c;但是菜鳥老是容易忘記&#xff0c;雖然想想或者搜搜就可以馬上寫出來&#xff0c;但是感覺每次那樣就太麻煩了&#xff0c;不如一股做氣寫了算了&#xff0c;后面遇見別的就再來補充&#xff01; 文章目錄 table 表格…

美創獲IDC數據庫安全市場代表廠商推薦,一路引領數據庫安全

近日&#xff0c;全球領先的IT市場研究和咨詢公司IDC發布《IDC Persepctive&#xff1a;中國數據庫安全市場洞察&#xff0c;2023》報告。 憑借多年的技術積累和豐富的產品體系與行業實踐&#xff0c;美創科技獲「代表廠商」推薦&#xff0c;再次彰顯專業領先能力&#xff01; …

Mybatis一級緩存和二級緩存原理剖析與源碼詳解

Mybatis一級緩存和二級緩存原理剖析與源碼詳解 在本篇文章中&#xff0c;將結合示例與源碼&#xff0c;對MyBatis中的一級緩存和二級緩存進行說明。 MyBatis版本&#xff1a;3.5.2 文章目錄 Mybatis一級緩存和二級緩存原理剖析與源碼詳解?級緩存場景一場景二?級緩存原理探究…

責任鏈模式 (Chain of Responsibility Pattern)

定義 責任鏈模式是一種行為型設計模式&#xff0c;用于在對象間建立一條處理請求的鏈。它允許多個對象有機會處理請求&#xff0c;從而減少請求的發送者和接收者之間的耦合。在責任鏈模式中&#xff0c;每個接收者包含對另一個接收者的引用&#xff0c;形成一條鏈。如果一個對…

tcp和 udp區別

相同點&#xff1a;都是傳輸層協議 不同點 是否面向連接 tcp:面向連接 三次握手&#xff0c;四次揮手端對端連接全雙工通信&#xff08;允許雙端同時收發數據&#xff09; udp:無連接 無三次握手&#xff0c;四次揮手支持一對一,一對多&#xff0c;多對多 數據傳輸方式 …

Linux平臺下使用.NET Core訪問Access數據庫

運行環境 操作系統&#xff1a;Ubuntu 22.04.3 LTS (Jammy)開發工具&#xff1a;Visual Studio 2022 (17.8.0)運行時版本&#xff1a;.NET Runtime 8.0依賴庫&#xff1a;unixodbc、mdbtools、odbc-mdbtools 依賴庫安裝 apt-get update sudo apt-get install unixodbc mdbto…

部署項目時常用的 Linux 命令

目錄 1 前言2 SSH登錄命令3 SCP傳輸命令4 CP拷貝命令5 MV移動命令6 TAR解壓命令7 DU查看文件夾/文件大小8 TAIL查看日志9 NOHUP后臺運行10 結語 1 前言 在應用部署過程中&#xff0c;Linux命令是必不可少的工具。它們能夠幫助我們管理文件、連接服務器、拷貝文件、查看日志以及…

vite項目配置vite.config.ts在打包過程中去除日志

在生產環境上&#xff0c;務必要將日志清除干凈&#xff0c;其因有二&#xff0c;在webgis系統中&#xff0c;有很多幾何數據&#xff0c;體積大、數量多&#xff0c;很容易引起系統卡頓&#xff1b;清除log后&#xff0c;系統看著舒服&#xff0c;協同開發有很多無聊的日志&am…

生日禮物——華為機考真題

題目描述 小牛的孩子生日快要到了&#xff0c;他打算給孩子買蛋糕和小禮物&#xff0c;蛋糕和小禮物各買一個&#xff0c; 他的預算不超過x元。蛋糕 Cake 和小禮物 gift 都有多種價位的可供選擇。 請返回小牛共有多少種購買方案。 輸入描述 第一行表示 Cake的單價, 以逗號分隔 …

字符串:leetcode1410. HTML 實體解析器

1410. HTML 實體解析器 「HTML 實體解析器」 是一種特殊的解析器&#xff0c;它將 HTML 代碼作為輸入&#xff0c;并用字符本身替換掉所有這些特殊的字符實體。 HTML 里這些特殊字符和它們對應的字符實體包括&#xff1a; 雙引號&#xff1a;字符實體為 &quot; &#xff…

一款非常優秀的項目管理工具:進度貓(推薦)

在項目管理中&#xff0c;一個好的工具可以極大地提高效率。 進度貓是一款非常優秀的項目管理工具。它具有非常強大的功能&#xff0c;可以幫助團隊更好地管理項目進度。 通過可視化的方式&#xff0c;將項目進度、任務分配、需求變更等全面呈現給團隊成員&#xff0c;讓團隊…

5.過濾敏感詞 + 發布帖子 + 帖子詳情

目錄 1.過濾敏感詞 1.1 定義前綴樹 1.2 根據敏感詞,初始化前綴樹 1.3 編寫過濾敏感詞方法

需求分析BSA法

&#x1f449;BSA法&#xff08;Basic–Satisfier–Attractor&#xff09;是對客戶需求進行優先級劃分的需求分析方法。該模型體現了需求滿足度和客戶滿意度之間的非線性關系。BSA法將客戶需求分為3種類型&#xff0c;分別是基本型需求、滿意型需求和興奮型需求。下面將對每種需…

ABB機 器 人 操 作 培 訓

目 錄 1 培訓手冊介紹 ---------------------------------------------2 2 系統安全與環境保護 ---------------------------------------------3 3 機器人綜述 ---------------------------------------------5 4 機器人示教 --------------------------------------------12…

哲學家就餐問題(java全代碼)

題目 有N個哲學家圍坐在一張圓桌旁&#xff0c;桌上只有N把叉子&#xff0c;每對哲學家中間各有一把。 哲學家的兩種行為&#xff1a; 一、思考 二、吃意大利面 哲學家只能拿起手邊左邊或右邊的叉子 吃飯需要兩把叉子 正確地模仿哲學家的行為 方法一 一次只允許四個人…

FSCTF2023-Reverse方向題解WP。學習貼

文章目錄 [FSCTF 2023]signin[FSCTF 2023]MINE SWEEPER[FSCTF 2023]Xor[FSCTF 2023]EZRC4[FSCTF 2023]ez_pycxor[FSCTF 2023]Tea_apk[FSCTF 2023]ezcode[FSCTF 2023]ezbroke[FSCTF 2023]rrrrust!!![FSCTF2023]ezrev&#xff08;未解決&#xff09; [FSCTF 2023]signin UPX殼&am…

redis-cluster集群模式

Redis-cluster集群 1 Redis3.0引入的分布式存儲方案 2集群由多個node節點組成,redis數據分布在節點之中,在集群之中分為主節點和從節點3集群模式當中,主從一一對應,數據寫入和讀取與主從模式一樣&#xff0c;主負責寫&#xff0c;從只能讀4集群模式自帶哨兵模式&#xff0c;可…

自然資源土地管理法律法規知識競賽這么辦才高端

近些年&#xff0c;全國各地自然資源廳舉辦了土地管理法律法規知識競賽&#xff0c;從我公司承辦的這些賽事來看&#xff0c;傳統的必答題、搶答題、風險題的方式已無法激起現場比賽氣氛&#xff0c;需要更加復雜有趣的環節設置及高端競賽軟件及其配套設備加持才可以讓知識競賽…