进程间的通信(IPC)--管道

news2024/11/19 2:40:02

1.进程间通信常用的方式

1 ,管道通信:有名管道,无名管道
2 ,信号 - 系统开销小
3 ,消息队列 - 内核的链表
4 ,信号量 - 计数器
5 ,共享内存
6 ,内存映射
7 ,套接字

2.管道的概念

2.1本质

*内核缓冲区
*伪文件 - 不占用磁盘空间

2.2特点

*两部分: 读端,写端,对应两个文件描述符 ,分别是数据写端流入,读端流出
* 操作管理的进程被销毁之后 管道自动被释放
*管道默认是阻塞的

2.3管道的原理

*内部实现方式:队列 ,环形队列
*特点:先进先出
*缓冲区大小 :默认4K ,大小会根据实际情况做适当调整

2.4管道的局限性

*队列: 数据只能读取一次,不能重复读取
*单工:遥控器
*半双工:对讲机

2.5管道的读写行为

读操作:
        有数据 :read(fd[1]) 正常读,返回读出的字节数
        无数据:如果写端被全部关闭时,read 返回 0 ,相当于读文件到了尾部。
                       如果写端没有全部关闭时,read阻塞
写操作:
        读端全部关闭:
                管道不断的写入数据可能管道会破裂,进程被终止 ,
                就是内核给当前进程发送信号SIGPIPE- 13,默认处理动作
        读端没全部关闭:
                缓冲区写满了:write 阻塞
                缓冲区没满   :write 继续写,直到写满,阻塞

2.6查看管道缓冲区大小

命令 :ulimit -a

3.无名管道

3.1无名管道的创建

函数:int pipe(int fd[2])
           fd‐传出参数:
           fd[0]‐ 读端
           fd[1]‐ 写端
返回值:
          0 :成功
          ‐1 :创建失败
历程:
include <unistd.h>
#include <stdio.h>
#include <stdlib.h>


int main()
{

        int fd[2];
        int rnt;

        rnt = pipe(fd);
        if(rnt == -1)
        {
                printf("创建无名管道失败\n");
                perror("pipe error");
                exit(0);
        }

        else
        {
                printf("读端:%d\n",fd[0]);
                printf("写端:%d\n",fd[1]);
        }
        close(fd[0]);
	    close(fd[1]);

        return 0;
}

运行结果:

3.2父子进程使用无名管道通信

示例:实现 ps aux| grep "bash"
示例功能:父进程使用 ps aux命令进行查询,子进程使用grep "bash"进行读取
数据重定向: dup2
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>



int main()
{

	int fd[2];
	int rnt;

	rnt = pipe(fd);
	if(rnt == -1)
	{
		printf("创建无名管道失败\n");
		perror("pipe error");
		exit(0);
	}
	pid_t pid = fork();

	if(pid == -1)
	{
		printf("fork failed!\n");
		perror("fork");
		exit(0);
	}
	if(pid == 0)//子进程进行读取数据,grep "bash"
	{
		printf("这是一个子进程\n");
		close(fd[1]);
		dup2(fd[0],STDIN_FILENO);//将要在终端读取数据,重定向到管道去读取
		execlp("grep","grep","bash","--color=auto",NULL);
		exit(0);
	}
    if(pid > 0)//父进程将数据写到管道里去 ps aux
	{
		close(fd[0]);//写之前要把管道的读关闭
		printf("这是一个父进程\n");
		dup2(fd[1],STDOUT_FILENO);//将数据重定向到管道去 不然就显示到终端了
		execlp("ps","ps","aux",NULL);
		wait(NULL);//阻塞回收子进程
		exit(0);
	}
	else
	{
		printf("读端:%d\n",fd[0]);
		printf("写端:%d\n",fd[1]);
	}

	close(fd[0]);
	close(fd[1]);

	return 0;
}
运行结果:
PS:进行管道读写的时候,读的时候要把写关闭,写的时候要把读关闭

3.3使用场景

有血缘关系的进程间通信(如:父子进程之间的通信)

4.有名管道

4.1有名管道的创建

函数形式: int mkfifo(const char \*filename,mode_t mode);
功能:创建管道文件
参数:管道文件文件名,权限,创建的文件权限仍然和 umask 有关系。
返回值:创建成功返回 0 ,创建失败返回 -1
e--1
write --2
read --4
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>

int main()
{
        int ret;

        ret = mkfifo("/home/czx/mkfifo",0777);
        if(ret == -1)
        {
                printf("有名管道创建失败\n");
                perror("myfifo");
                return -1;
        }
        else
                printf("有名管道创建成功\n");

        return 0;
}
~

运行结果:

PS :创建管道的时候,只会创建一个指向内核缓冲区的节点,调用open()的时候才会生成管道.

示例:
功能:一个进程利用管道进行读取数据,一个进程利用管道进行写数据
利用管道进行读数据:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
        int ret;
        char readBuff[20] = {0};
        int read_ret;
        int fd;
        ret = mkfifo("/home/czx/mkfifo",0775);
        if(ret == -1)
        {
                printf("有名管道创建失败\n");
                perror("myfifo");
                return -1;
        }
        else
        {
                printf("有名管道创建成功\n");
                fd = open("/home/czx/mkfifo",O_RDONLY);
                if(fd < 0)
                {
                        printf("打开管道错误\n");
                        return -2;
                }
                else
                {
                        while(1)
                        {
                                read_ret = read(fd,readBuff,20);
                                printf("读取到的字节数%d,内容为:%s\n",read_ret,readBuff);

                        }
                }
        }
        close(fd);

        return 0;
}

利用管道进行写数据:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
        char writeBuff[20];
        int fd;
        fd = open("/home/czx/mkfifo",O_WRONLY);
        if(fd < 0)
        {
                printf("打开管道错误\n");
                return -2;
        }
        else
        {
                while(1)
                {
                        gets(writeBuff);
                        write(fd,writeBuff,20);
                }
        }
        close(fd);

        return 0;
}
~       

运行结果:

4.2特点

有名管道
在磁盘上有这样一个文件 ls -l ->p
也是一个伪文件,在磁盘大小永久为 0
数据存在内核中有一个对应的缓冲区
半双工通信方式

4.3使用场景

没有血缘关系的进程间通信

4.4创建方式

命令: mkfifo 管道名
函数: mkfifo

4.5.fifo文件可以使用io函数进程操作

open/close
read/write
不能执行 lseek 操作

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1955356.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

人称“灯爷”的灯光师到底要做些什么,看看他的岗位说明书

灯光师又称“灯爷”,是摄影制作部门负责灯光设备的技术人员,一般归摄影指导调配。被尊称“爷”,可见灯光师的地位不容小觑。那么这个岗位到底要做些什么呢&#xff1f; 岗位职责&#xff1a; 1、负责公司灯光设备的调制、维护和保养&#xff1b; 2、负责各包房灯光设备的调制、…

Mac环境报错 error: symbol(s) not found for architecture x86_64

Mac 环境Qt Creator报错 error: symbol(s) not found for architecture x86_64 错误信息 "symbol(s) not found for architecture x86_64" 通常是在编译或链接过程中出现的问题。这种错误提示通常涉及到符号未找到或者是因为编译器没有找到适当的库文件或函数定义。 …

基于springboot+vue+uniapp的养老院系统小程序

开发语言&#xff1a;Java框架&#xff1a;springbootuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#…

初识git工具~~上传代码到gitee仓库的方法

目录 1.背景~~其安装 2.gitee介绍 2.1新建仓库 2.2进行相关配置 3.拉取仓库 4.服务器操作 4.1克隆操作 4.2查看本地仓库 4.3代码拖到本地仓库 4.4关于git三板斧介绍 4.4.1add操作 4.4.2commit操作 4.4.3push操作 5.一些其他说明 5.1.ignore说明 5.2git log命令 …

ACC:Automatic ECN Tuning for High-Speed Datacenter Networks 相关知识点介绍(二)

目录 PerfTest工具 Incast traffic Incast Traffic 的原因 Incast Traffic 的影响 解决方法 流量负载 简单解释 影响因素 影响 管理方法 LINKPACK 主要特点 LinkPack 的应用 运行结果 Quantum ESPRESSO 主要特点 TensorFlow 主要特点 主要组件 Incast与qp …

Ubuntu2023.04 浏览器不能上网的问题

1.问题描述 ping www.baidu.com 是可以连接的&#xff0c;但是打开网页就是不能上网&#xff0c;但是自己查看了浏览器上面的设置&#xff0c;代理设置都是关闭的 再看了系统的设置代理也是关闭的&#xff0c;就是上不了网 解决方案&#xff1a; 455 echo $http_proxy456 e…

JavaWeb项目中动态拼接sql语句

业务需求描述&#xff1a; 图中的查询框在分条件查询用户信息列表时&#xff0c;前端可能会传回一个条件或多个条件&#xff0c;此时要对不同的条件进行sql语句的不同书写&#xff0c;前端传的情况有很多种&#xff0c;所以如果分情况写sql语句会比较死&#xff0c;并且不够灵活…

机器学习之人脸识别-使用 scikit-learn 和人工神经网络进行高效人脸识别

文章摘要 本文将介绍如何使用 Python 的 scikit-learn 库和人工神经网络&#xff08;ANN&#xff09;来识别人脸。我们将使用 LFW 数据集&#xff08;Labeled Faces in the Wild&#xff09;&#xff0c;这是一个广泛用于人脸识别基准测试的大型人脸数据库。我们将展示如何准备…

RedHat Enterprise Linux 7 YUM源(本地/网络源)配置详解

目录 一、挂载 二、建立本地源 三、建立网络源 四、验证可行性 一、挂载 ——将光盘挂载到 /mnt 下 当/mnt中有如图内容时&#xff0c;即挂载成功 若挂载光驱/dev/sr0时报错&#xff1a;mount: no medium found on /dev/sr0 解决措施&#xff1a;查看该设备状态是否全部勾选…

数仓实践:一文读懂数仓 ODS 层模型设计

引言 OneData 体系中,数据划分为三层: ODS(Operational Data Store):操作数据层。它相当于数据中台通用数据模型层的一个数据准备区,同时又承担着基础数据的记录以及历史变化,主要完成业务系统、日志等结构化和半结构化数据引入到数据中台。保留业务系统原始数据,包括…

【HZHY-AI300G智能盒试用连载体验】设置RKNN的开发环境

目录 安装RKNN工具 安装pip3 安装RKNN Toolkit Lite2 安装RKNPU2运行库 本文首发于电子发烧友论坛&#xff1a;【新提醒】【HZHY-AI300G智能盒试用连载体验】 智能工业互联网网关 - 北京合众恒跃科技有限公司 - 电子技术论坛 - 广受欢迎的专业电子论坛! (elecfans.com) 前…

WordPress文章标题定制化前缀插件

引言 在当今互联网的海洋中&#xff0c;吸引读者眼球的第一步往往始于文章标题的设计。对于WordPress博主而言&#xff0c;如何让每篇文章的标题更加个性化和吸引人&#xff0c;成为了一项重要的任务。传统的自定义CSS方法虽然可行&#xff0c;但其繁琐的操作和有限的美学效果…

麦克斯韦方程组解析——电磁理论的基石与奥秘

麦克斯韦方程组解析——电磁理论的基石与奥秘 麦克斯韦方程组的核心作用 组件/步骤描述麦克斯韦方程组描述电磁场的基本方程组&#xff0c;由四个主要方程构成功能揭示电场、磁场与电荷、电流之间的关系&#xff0c;是电磁理论的基础应用领域广泛应用于电子学、光学、通信等领…

51单片机16(步进电机实验)

一、步进电机简介&#xff1a; 1、步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件。 2、 3、 4、我们这个电机的旋转停止的位置只取决于脉冲信号的频率和脉冲数&#xff0c;而不受负载的变化的影响&#xff0c;也就是说给我们的这个步进电机一个脉冲信号&#x…

大唐杯 5G LMT

一、比赛现场流程 比赛现场会给你一个册子&#xff0c;册子前边部分会告诉你要做什么&#xff0c;最后一页会给参数。 按照他告诉你要做什么一步步根据参数做就可以了。 他每组还会有个评分表&#xff0c;按照一步步的操作给你打分。 我们评分表这次是 基站登录—网络规划参…

猫用空气净化器测评分享,猫用空气净化器哪个牌子值得买?

作为一位5年资深铲屎官&#xff0c;很多铲屎官听过一丁半点宠物空气净化器&#xff0c;知道宠物空气净化器净化器对于养猫家庭的重要性。其实宠物空气净化器真的是养猫家庭必备的一款小家电。大面积进风口可以有效吸附空气中微小的浮毛、皮屑&#xff0c;专门的除臭技术有效净化…

DP 整数拆分不同的二叉搜索树 DAY21

整数拆分&#xff1f; 给定一个正整数 n &#xff0c;将其拆分为 k 个 正整数 的和&#xff08; k > 2 &#xff09;&#xff0c;并使这些整数的乘积最大化。 返回 你可以获得的最大乘积。 示例 1: 输入: n 2 输出: 1 解释: 2 1 1, 1 1 1。示例 2: 输入: n 10 输…

后端笔记(1)--javaweb简介

1.JavaWeb简介 ​ *用Java技术来解决相关web互联网领域的技术栈 1.网页&#xff1a;展现数据 2.数据库&#xff1a;存储和管理数据 3.JavaWeb程序&#xff1a;逻辑处理 2.mysql 1.初始化Mysql mysqld --initialized-insecure2.注册Mysql服务 mysqld -install3.启动Mysql…

数据结构第六讲:栈和队列

数据结构第六讲&#xff1a;栈和队列 1.栈1.1概念与结构1.2栈的实现1.2.1栈的基础框架1.2.2栈的初始化1.2.3栈的销毁1.2.4栈的插入&#xff08;压栈&#xff09;1.2.5栈的删除&#xff08;出栈&#xff09;1.2.6获取栈顶元素1.2.7获取栈中有效数据的个数 2.队列2.1概念与结构2.…