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.mzph.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…