Linux(十四)進程間通信(IPC),管道

一、進程間通信

(一)系統介紹進程間通信

進程間通信(IPC)介紹

小編插入的這篇文章詳細介紹了進程間通信的一些內容,大家可以一起學習。

(二)進程間通信的方法

1、管道

2、信號量

3、共享內存

4、消息隊列

5、套接字

? ? ? ? 接下來的幾篇文章,小編就會按照順序介紹這幾種方法(加粗的為重點內容),今天首先要學到的是管道。

二、管道

? ? ? ? 關于管道這個詞,其實我們在之前有過一點點了解,不知道大家還是否記得。在Linux(四)基礎命令2中,| 代表管道,當時是和grep(過濾)搭配使用。今天,我們就正式接觸管道這個內容了。

? ? ? ? 首先是管道的分類,分為有名管道(命名管道)無名管道。它們的區別有名管道在任意兩個進程間通信,無名管道在父子進程之間通信

(一)有名管道

1、創建有名管道? ?mkfifo

2、打開管道? ?open()

3、關閉管道? ?close()

4、讀數據? ?read()

5、寫入數據? ?write()

? ? ? ? 在學習完上面的操作后,我們來思考一個問題:如果進程a要從鍵盤獲取數據傳遞給另一個進程b,不使用管道操作應該如何完成?

? ? ? ? 其實在C語言中,我們可以通過文件操作完成,但是通過文件進行進程間通信存在兩個問題:(1)速度慢(2)讀數據時不知道a什么時候會寫入。

? ? ? ? 下面,大家就和小編一起通過有名管道來演示進程間通信。

? ? ? ? 管道創建之后,它會在內存上分配一塊空間(也就是通過管道的數據存在了內存中),而管道本身在磁盤里,所以管道的大小永遠為0

? ? ? ? 管道有兩端(大家可以想象一下它想一個水管有兩頭),一端為讀端,一端為寫端(就像水管一遍流入一遍流出)。即管道一個是讀打開,一個是寫打開。

? ? ? ? 讓我們將下面的代碼在終端中寫入,進行演示。

//a.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<assert.h>
#include<fcntl.h>
#include<string.h>int main(){int fd = open("fifo",O_WRONLY);//當前路徑可以省略,絕對路徑要寫全assert(fd!=-1);printf("fd = %d\n",fd);write(fd,"hello",5);close(fd);
}
//b.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<assert.h>
#include<fcntl.h>int main(){int fd = open("fifo",O_RDONLY);assert(fd!=-1);printf("fd = %d\n",fd);char buf[128] = {0};read(fd,buf,127);printf("read:%s\n",buf);close(fd);exit(0);
}

我們打開兩個終端界面。

? ? ? ? 下面我們將上面的代碼進行修改,使a循環寫入(從鍵盤寫入),b循環讀取。

//a.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<assert.h>
#include<fcntl.h>
#include<string.h>int main(){int fd = open("fifo",O_WRONLY);//當前路徑可以省略,絕對路徑要寫全assert(fd!=-1);printf("fd = %d\n",fd);while(1){   printf("input:\n");char buff[128] = {0};fgets(buff,128,stdin);if(strncmp(buff,"end",3)==0){break;}write(fd,buff,strlen(buff));}   close(fd);
}//b.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<assert.h>
#include<fcntl.h>int main(){int fd = open("fifo",O_RDONLY);assert(fd!=-1);printf("fd = %d\n",fd);while(1){char buf[128] = {0};if(read(fd,buf,127)==0)//用于驗證管道寫端關閉,讀read返回值為0(第3個特點){break;}printf("read:%s\n",buf);}   close(fd);exit(0);
}

通過上面這兩個個例子,我們來總結一下管道的特點

? ? ? ? (1)管道必須讀,寫進程同時open,否則會阻塞;

????????(2)如果管道沒有數據,那么read會阻塞;????

????????(3)管道的寫端關閉,讀read返回值為0;

? ? ? ? (4)管道打開的時候只有只讀和只寫兩種方式,讀寫方式打開是未定義的。? ? ? ? ? ?

(二)無名管道

? ? ? ? 有名管道之所以不限制進程,就是因為它有名字可以被找到;而無名管道不可以,如果不限制進程,它又沒有名字,我們就沒有辦法找到它了。因此,無名管道只能用于父子進程間通信。

? ? ? ? 創建無名管道? ?pipe

還是同樣的思路,學習一個新的命令要使用幫助手冊 man pipe。

//fi.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<assert.h>
#include<fcntl.h>
#include<string.h>int main(){int fd[2];assert(pipe(fd)!=-1);pid_t pid = fork();assert(pid!=-1);//先open 后fork 共享文件描述符if(pid==0){   close(fd[1]);char buff[128] = {0};read(fd[0],buff,127);printf("child read:%s\n",buff);close(fd[0]);} else{close(fd[0]);write(fd[1],"hello",5);close(fd[1]);}exit(0);
}

?通過上面兩個例子,下面小編帶領大家總結一下管道的特點:

? ? ? ? (1)管道必須讀,寫進程同時open,否則會阻塞;

? ? ? ? (2)如果管道沒有數據,那么read會阻塞;

? ? ? ? (3)管道的寫端關閉,讀read返回值為0;

? ? ? ? (4)管道打開的時候只有只讀和只寫兩種方式,讀寫方式打開是未定義的;

? ? ? ? (5)無論有名還是無名,寫入管道的數據都在內存中(管道的大小永遠為0,面試的重點)

? ? ? ? (6)管道是一種半雙工通信方式(通信方式有單工,半雙工,全雙工)

? ? ? ? (7)有名管道和無名管道的區別:有名管道可以在任意進程間使用,無名管道主要在父子進程
間通信

? ? ? ? (8)管道的讀端關閉,寫會產生異常(發送信號SIGPIPE)

小編通過改變a.c的代碼來進行驗證,代碼如下:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<assert.h>
#include<fcntl.h>
#include<string.h>
#include<signal.h>
void sig_fun(int sig){printf("sig = %d\n",sig);
}
int main(){signal(SIGPIPE,sig_fun);int fd = open("fifo",O_WRONLY);//當前路徑可以省略,絕對路徑要寫全assert(fd!=-1);printf("fd = %d\n",fd);while(1){   printf("input:\n");char buff[128] = {0};fgets(buff,128,stdin);if(strncmp(buff,"end",3)==0){break;}write(fd,buff,strlen(buff));}   //write(fd,"hello",5);close(fd);
}

(三)管道的實現

通過上面的圖片,我們可以直到管道其實就是一個循環隊列。

如果管道是空的,讀操作會堵塞;如果管道是滿的,寫操作會堵塞。

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

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

相關文章

使用Homebrew下載配置git和連接GitHub(Mac版)

本文詳細介紹了在M系列Mac上安裝Homebrew并配置Git的過程&#xff0c;包括git的下載、設置全局用戶名和郵箱、生成SSH密鑰、添加GitHubSSH密鑰以及終端驗證。這些步驟有助于用戶順利進行協同開發。 一、下載git 1、終端輸入一下命令 brew install git2、這時下載完成 二、配…

懸崖邊的攝影牧歌

在云霧繚繞的懸崖邊&#xff0c;一場獨屬于自然與光影的邂逅悄然上演。 攝影師佇立于此&#xff0c;身旁是一群靈動的羊。他架起相機&#xff0c;眼神專注而熾熱&#xff0c;仿佛要將這天地間的一切都收納進小小的取景器。懸崖陡峭&#xff0c;巖石冷峻&#xff0c;卻因羊群的潔…

Linux環境基礎與開發工具使用

1. Linux編譯器vim 1.1 vim的基本概念講解 vim有很多種模式&#xff0c;我們初學者常用的就是命令模式&#xff08;command mode&#xff09;、插入模式&#xff08;Insert mode&#xff09;和底行模式&#xff08;last line mode&#xff09;。 命令/正常模式(Normal mode) …

《Python星球日記》 第36天:線性代數基礎

名人說&#xff1a;路漫漫其修遠兮&#xff0c;吾將上下而求索。—— 屈原《離騷》 創作者&#xff1a;Code_流蘇(CSDN)&#xff08;一個喜歡古詩詞和編程的Coder&#x1f60a;&#xff09; 專欄&#xff1a;《Python星球日記》&#xff0c;限時特價訂閱中ing 目錄 一、標量、…

使用VMware Workstation pro 17.5.1在Windows上安裝Ubuntu 24.04.2的 詳細步驟

一、準備工作 1. 下載Ubuntu 24.04.2 ISO鏡像 官方下載地址&#xff1a;Ubuntu 24.04.2 (Noble Numbat) 選擇 ubuntu-24.04.2-desktop-amd64.iso&#xff08;桌面版&#xff09;或 ubuntu-24.04.2-live-server-amd64.iso&#xff08;服務器版&#xff09;。 2. 確認系統要求…

ios systeam introduction

Here is an in-depth look at Apple’s iOS, from its inception to its latest major release, covering architecture, core components, security, app lifecycle, development tools, and the headline features of iOS 18. iOS began life as “iPhone OS,” unveiled alo…

優化04-選擇率和直方圖

選擇率 在Oracle數據庫中&#xff0c;選擇率&#xff08;Selectivity&#xff09; 是優化器&#xff08;CBO&#xff0c;基于成本的優化器&#xff09;用來評估SQL語句中某個條件&#xff08;如WHERE子句&#xff09;過濾數據的比例的關鍵指標。它直接影響優化器選擇執行計劃的…

python實戰:通過輸入文字匹配在docx文檔中的具體位置

在指定的docx文檔中,輸入一串文字來查看該文字在文檔中的具體位置;方便后續處理(如替換文字,高亮顯示等等操作) from docx import Documentdef find_text_in_docx(file_path, search_text):# 讀取docx文件doc = Document(file_path)# 遍歷段落,查找匹配的文本for i

Flutter——數據庫Drift開發詳細教程(二)

目錄 1.核心API1.1查詢數據列表分頁1.2 列表排序1.3推遲獲取與觀察 1.核心API 1.1查詢數據列表分頁 限制返回的結果數量limit&#xff0c;從某一位置開始查詢offset ///limit10, offset10 Future<List<TodoItem>> limitTodos(int limit, {int? offset}) {return …

mux-vlan基礎配置

1.top配置 2.各個交換機設置 sw3交換機的 sysname swb # undo info-center enable # vlan batch 10 20 30 100 # vlan 10description financial vlan vlan 20description marketing vlan vlan 30description client vlan vlan 100description principal vlanmux-vlansubordi…

SAM詳解2(初級應用)

SAM SAM5. 初級應用5.1 靜態本質不同子串個數5.2 字符串匹配5.3 關于子串出現次數5.4 動態添加時本質不同子串個數SAM 5. 初級應用 記 l o n g e s t ( x ) longest(x) longest(x) 為點 x x x 代表子串集合中最長串的長度。記 s h o r t e s t ( x ) shortest(x) shortest(…

【日擼 Java 三百行】Day 4(條件語句實戰——閏年問題)

目錄 Day 4&#xff1a;條件語句實戰——閏年問題 一、基礎知識及代碼思路 二、代碼及測試 小結 Day 4&#xff1a;條件語句實戰——閏年問題 Task&#xff1a; if 語句的嵌套.基本規律自行百度.布爾類型. 一、基礎知識及代碼思路 1. 什么是閏年&#xff1f; 閏年是歷法中…

MySQL 中 EXISTS (SELECT 1 FROM ...) 的用法詳解

EXISTS (SELECT 1 FROM ...) 是 MySQL 中用于存在性檢查的核心語法&#xff0c;其核心邏輯是判斷子查詢是否返回至少一行數據。以下從作用原理、使用場景、性能優化等方面展開解析&#xff0c;并結合具體示例說明。 1. 基本語法與作用原理 語法結構&#xff1a; SELECT 列名 F…

阿里云服務器防御是怎么做出來的?服務器攻擊方式有幾種?

阿里云服務器防御是怎么做出來的?服務器攻擊方式有幾種&#xff1f; 服務器防御是一個多層次、多維度的體系&#xff0c;通常包括以下核心措施&#xff1a; 1. 網絡層防御 防火墻&#xff08;Firewall&#xff09;&#xff1a;過濾非法流量&#xff0c;僅允許授權通信&#xf…

ElasticSearch深入解析(八):索引設置、索引別名、索引模板

一、索引的動態設置、靜態設置 索引設置包含兩部分核心內容&#xff1a; 靜態設置(static index settings)&#xff0c;只允許在創建索引時或者針對已關閉的索引進行設置。指動態設置(dynamic index settings)&#xff0c;可以借助更新設置(update settings)的方式進行動態更新…

Prometheus實戰教程:k8s平臺手動部署Grafana

以下是一個可用于生產環境的 Kubernetes 部署 Grafana 的 YAML 文件。該配置包括 Deployment、Service、ConfigMap 和 PersistentVolumeClaim&#xff0c;確保 Grafana 的高可用性和數據持久化。 Grafana 生產部署 YAML 文件 ☆實操示例 cat grafana-deployment.yaml 登錄后復制…

VSTO外接程序與VBA的聯動嘗試

文章目錄 前言一、第一坑&#xff1a;安裝offic2007后excel加載項找不到了二、示例1 通過Ribbon XML自定義Excel主菜單并添加新項二、示例1 總結三、示例2 創建VSTO外接程序三、示例2 總結四、示例 3 C# VSTO外接程序示例四、示例 3 總結五、實現C# 的VSTO調用VBA函數(xlam)六、…

DeepSeek驅動的金市情緒量化:NLP解析貿易政策文本的情緒傳導路徑

【AI觀察】政策信號與市場情緒的量化關聯 基于自然語言處理技術對全球財經文本的情緒分析顯示&#xff0c;4月30日亞盤時段現貨黃金價格波動率較前日下降12.3%&#xff0c;與技術面修正指標呈現強相關性。特政府最新關稅政策調整引發市場風險偏好指數&#xff08;RPI&#xff…

期末代碼Python

以下是 學生信息管理系統 的簡化版代碼示例&#xff08;控制臺版本&#xff0c;使用文件存儲數據&#xff09;&#xff0c;包含核心功能&#xff1a; 1. 定義學生類 class Student: def __init__(self, sid, name, score): self.sid sid # 學號 self.name name # 姓名 self.s…

zotero pdf中英翻譯插件使用

最近發現一個pdf中英翻譯的神器zotero-pdf2zh&#xff0c;按照官方安裝教程走一遍的時候&#xff0c;發現一些流程不清楚的問題&#xff0c; 此文就是整理一些安裝需要的文件以及遇到的問題&#xff1a; 相關文件下載地址 Zotero 是一款免費的、開源的文獻管理工具&#xff0…