Linux多进程(二)进程通信方式一 管道

管道的是进程间通信(IPC - InterProcess Communication)的一种方式,管道的本质其实就是内核中的一块内存(或者叫内核缓冲区),这块缓冲区中的数据存储在一个环形队列中,因为管道在内核里边,因此我们不能直接对其进行任何操作。

因为管道数据是通过队列来维护的,我们先来分析一个管道中数据的特点:

  • 管道对应的内核缓冲区大小是固定的,默认为4k(也就是队列最大能存储4k数据)
  • 管道分为两部分:读端和写端(队列的两端),数据从写端进入管道,从读端流出管道
  • 管道中的数据只能读一次,做一次读操作之后数据也就没有了(读数据相当于出队列)
  • 管道是单工的:数据只能单向流动, 数据从写端流向读端
  • 对管道的操作(读、写)默认是阻塞的

一、匿名管道

匿名管道是管道的一种,既然是匿名也就是说这个管道没有名字,但其本质是不变的,就是位于内核中的一块内存,匿名管道拥有上面介绍的管道的所有特性。

pipe 函数用于创建一个管道,以实现进程间通信。

#include <unistd.h>int pipe(int fd[2]);

管道容量的大小默认是65536字节。我们可以使用fcntl函数来修改管道容量。

下面举一个在多进程程序中管道通信的例子:

#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>int main()
{int pipefd[2];char buf[1024];// 创建管道if (pipe(pipefd) == -1){perror("pipe error! \n");return 1;}for (int i = 0; i < 8; i++){// 创建子进程pid_t pid = fork();if (pid == -1){perror("fork error!\n");return 1;}else if (pid == 0){// 子进程关闭写端close(pipefd[1]);// 从管道读取数据memset(buf, 0, 1024);read(pipefd[0], buf, sizeof(buf));// 打印数据printf("pid = %d :Child process received: %s\n", getpid(), buf);// 子进程关闭读取端close(pipefd[0]);// 子进程直接break,以免创建更多的子进程break;}}if (getpid() != 0){// 父进程关闭读取端close(pipefd[0]);// 向管道写入数据const char *message = "Hello from parent process";for (int i = 0; i < 8; i++){write(pipefd[1], message, strlen(message));sleep(1);}// 在所有数据都写入后再关闭写入端close(pipefd[1]);}return 0;
}

生成了八个子进程,八个子进程阻塞在read处,等待父进程的消息,父进程发了八次消息,每次间隔1秒。看一下仿真
请添加图片描述

二、有名管道

有名管道拥有管道的所有特性,之所以称之为有名是因为管道在磁盘上有实体文件, 文件类型为p ,有名管道文件大小永远为0,因为有名管道也是将数据存储到内存的缓冲区中,打开这个磁盘上的管道文件就可以得到操作有名管道的文件描述符,通过文件描述符读写管道存储在内核中的数据。

有名管道也可以称为 fifo (first in first out),使用有名管道既可以进行有血缘关系的进程间通信,也可以进行没有血缘关系的进程间通信。创建有名管道的方式有两种,一种是通过命令,一种是通过函数。

2.1、创建有名管道

通过命令

mkfifo 有名管道的名字

通过函数

#include <sys/types.h>
#include <sys/stat.h>int mkfifo(const char *pathname, mode_t mode);
  • pathname: 要创建的有名管道的名字
  • mode: 文件的操作权限, 和open()的第三个参数一个作用,最终权限: (mode & ~umask)
  • 返回值:创建成功返回 0,失败返回 -1

2.2、进程间通信

不管是有血缘关系还是没有血缘关系,使用有名管道实现进程间通信的方式是相同的,就是在两个进程中分别以读、写的方式打开磁盘上的管道文件,得到用于读管道、写管道的文件描述符,就可以调用对应的read()、write()函数进行读写操作了。

有名管道操作需要通过 open() 操作得到读写管道的文件描述符,如果只是读端打开了或者只是写端打开了,进程会阻塞在这里不会向下执行,直到在另一个进程中将管道的对端打开。

写管道的进程

#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>int main()
{// 1. 创建有名管道文件int ret = mkfifo("./testfifo", 0664);if(ret == -1){perror("mkfifo");exit(0);}printf("管道文件创建成功...\n");// 2. 打开管道文件int wfd = open("./testfifo", O_WRONLY);if(wfd == -1){perror("open");exit(0);}printf("以只写的方式打开文件成功...\n");// 3. 循环写管道int i = 0;while(i<100){char buf[1024];sprintf(buf, "hello, fifo, 我在写管道...%d\n", i);write(wfd, buf, strlen(buf));i++;sleep(1);}close(wfd);return 0;
}

读管道的进程

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>int main()
{// 1. 打开管道文件int rfd = open("./testfifo", O_RDONLY);if(rfd == -1){perror("open");exit(0);}printf("以只读的方式打开文件成功...\n");// 2. 循环读管道while(1){char buf[1024];memset(buf, 0, sizeof(buf));// 读是阻塞的, 如果管道中没有数据, read自动阻塞int len = read(rfd, buf, sizeof(buf));printf("读出的数据: %s\n", buf);if(len == 0){// 写端关闭了, read解除阻塞返回0printf("管道的写端已经关闭, 拜拜...\n");break;}}close(rfd);return 0;
}

仿真结果

请添加图片描述

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

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

相关文章

Vue 双向绑定、diff和nextTick原理

前言 什么是虚拟dom virtual DOM 虚拟DOM&#xff0c;用普通js对象来描述DOM结构&#xff0c;因为不是真实DOM&#xff0c;所以称之为虚拟DOM。 虚拟 dom 是相对于浏览器所渲染出来的真实 dom而言的&#xff0c;在react&#xff0c;vue等技术出现之前&#xff0c;我们要改变页面…

LabVIEW专栏八、类

该章目的是可以开发仪器类。 一、类的概述 一般来说类有三大特性&#xff0c;封装&#xff0c;继承和多态。 在实际项目中&#xff0c;最主要是继承和多态&#xff0c;要搞清楚这两者的概念和在LabVIEW中是怎样应用的。在LabVIEW中&#xff0c;面向对象编程用到的就是LabVIE…

Mac 上可以使用 ping 端口

在 Mac 上可以使用 ping 命令来检查与另一台计算机或网络设备的连通性。要 ping 一个端口&#xff0c;你需要使用另一个命令 nc&#xff08;也称为 netcat&#xff09;。 例如&#xff0c;假设你想要 ping 端口 8080&#xff08;通常用于 HTTP 代理服务器&#xff09;&#xf…

SAM在低阶自适应航空土地覆盖分类中的应用2024.01

GEOSCIENCE AND REMOTE SENSING LETTERS 2024.01 提出了一种新的语义分割模型&#xff0c;该模型结合了SAM的图像编码器和低秩自适应方法(LoRA)&#xff0c;用于航空图像的特征提取和微调。我们还使用了一个辅助CNN编码器来促进下游适应&#xff0c;并补充ViT编码器在密集视觉…

机器学习模型效果不好及其解决办法

当训练出来的机器学习模型效果不佳时&#xff0c;可能涉及多个方面的原因。为了改善模型的效果&#xff0c;需要系统地检查和分析问题的根源&#xff0c;并采取相应的措施进行优化。 一、数据问题 数据质量 检查数据是否干净、完整&#xff0c;是否存在噪声、异常值或缺失值。…

【MySQL】A01、性能优化-语句分析

1、数据库优化方向 A、SQL及索引优化 根据需求写出良好的SQL&#xff0c;并创建有效的索引&#xff0c;实现某一种需求可以多种写法&#xff0c;这时候我们就要选择一种效率最高的写法。这个时候就要了解sql优化 B、数据库表结构优化 根据数据库的范式&#xff0c;设计表结构&…

MAC 安装miniconda

Conda Conda是一个开源跨平台语言无关的包管理与环境管理系统。由“连续统分析”基于BSD许可证发布。 Conda允许用户方便地安装不同版本的二进制软件包与该计算平台需要的所有库。还允许用户在不同版本的包之间切换、从一个软件仓库下载包并安装。 Conda是用Python语言开发&am…

从C向C++14——STL初识及函数对象

一.STL初识 1.STL的诞生 长久以来&#xff0c;软件界一直希望建立一种可重复利用的东西C的面向对象和泛型编程思想&#xff0c;目的就是复用性的提升多情况下&#xff0c;数据结构和算法都未能有一套标准,导致被迫从事大量重复工作为了建立数据结构和算法的一套标准,诞生了ST…

详解汽车充电桩主板的硬件设计与软件系统

随着电动汽车时代的到来&#xff0c;充电桩逐渐成为城市新地标。而在每一个充电桩的核心&#xff0c;隐藏着一颗强大的“心脏”——充电桩主板。 充电桩主板是充电桩的核心部件&#xff0c;决定着充电桩的充电效率、安全和用户体验。今天&#xff0c;我们将深入探索汽车充电桩主…

数学分析复习:三角函数的周期性

文章目录 三角函数的周期性 本篇文章适合个人复习翻阅&#xff0c;不建议新手入门使用 三角函数的周期性 本节的主题是研究三角函数的周期性&#xff0c;我们之前已经解析地定义三角函数为 cos ⁡ x ∑ k 0 ∞ ( − 1 ) k x 2 k ( 2 k ) ! , sin ⁡ x ∑ k 0 ∞ ( − 1 )…

Java并发编程之锁的艺术:面试与实战指南(二)

1. Java中线程和进程的区别是什么&#xff1f; 进程是系统分配资源的基本单位&#xff0c;它包含了一个或多个线程以及相关的系统资源&#xff08;如内存、文件句柄等&#xff09;。进程间相互独立&#xff0c;通过进程间通信&#xff08;IPC&#xff09;进行信息交换。线程是…

分布式版本控制工具 Git 的使用方式

文章目录 Git简介下载安装基本使用起始配置Git 的三个区域基本操作流程查看仓库状态删除&#xff08;撤销暂存区&#xff09;差异对比查看版本日志版本回退修改提交日志分支概念&#xff1a;创建分支与切换分支合并分支&#xff08;快速合并&#xff09;合并分支&#xff08;提…

jQuery中的api操作

1、认识jQuery jQuery函数 , jQuery的别 "$" , $也是一个函数. // $(function(){})// $ 是什么? $ 是一个函数// console.log(typeof $);// function// $ 是jQuery的别名?// window.jQuery window.$ jQuery;// console.log(jQuery $);// true 2、文档遍历和操…

北京筑龙当选中招协第二届招标采购数字化专业委员会执行主任单位

4月18-19日&#xff0c;中国招标投标协会&#xff08;以下简称中招协&#xff09;2024年年会在宁波召开&#xff0c;北京筑龙作为中招协理事会员单位受邀出席会议。会议期间举行了“电子招标采购专业委员会换届会议暨第二届第一次工作会议”&#xff0c;北京筑龙当选第二届招标…

用代码给孩子造“钱”

起因 作为家里有两个娃的奶爸&#xff0c;时长为了孩子乱花钱而焦虑不已。然后最近看到一段短视频说了这么段话。 父母不要被动给孩子买东西&#xff0c;而是定期给孩子钱。让孩子自己管钱培养她对于钱的认知和理财的观念。 突然感觉大师我悟了。感觉值得一试。于是就打算给他…

如何在官网查看Qt5的所有模块?

2024年4月23日&#xff0c;周二上午 如果你不想一步步来的话&#xff0c;可以直接去这个Qt官方链接 https://doc.qt.io/qt-5/qtmodules.html 第一步&#xff1a;去到Qt官网 https://www.qt.io/ 第二步&#xff1a;点击文档链接 第三步&#xff1a;选择文档中的“Qt5” 第四步…

Python项目开发实战:如何自动化读取Excel数据文件并用可视化分析

注意:本文的下载教程,与以下文章的思路有相同点,也有不同点,最终目标只是让读者从多维度去熟练掌握本知识点。 下载教程:Python项目开发实战_自动化读取Excel数据文件并用可视化分析_编程案例实例课程教程.pdf 1、可视化分析的特点 在Python项目开发实战中,可视化分析扮…

Python中的tkinter工具包帮助文档查询以及Python其他GUI工具包分类

Python中的tkinter工具包帮助文档查询以及Python其他GUI工具包分类 虽然Python支持许多GUI工具包&#xff0c;然而Tkinter是Python的实际标准GUI&#xff08;图形用户界面&#xff09;包&#xff0c;也是最常用的一种。本文简要介绍tkinter工具包帮助文档查询以及Python其他GU…

SpanBert学习

SpanBERT: Improving Pre-training by Representing and Predicting Spans 核心点 提出了更好的 Span Mask 方案&#xff0c;也再次展示了随机遮盖连续一段字要比随机遮盖掉分散字好&#xff1b;通过加入 Span Boundary Objective (SBO) 训练目标&#xff0c;增强了 BERT 的性…

flask_apscheduler 定时任务框架

简介 Flask_apscheduler是一个在Flask框架中使用的APScheduler库的扩展。APScheduler是一个用于调度任务的Python库&#xff0c;可以在指定的时间间隔调度函数、方法或任意可调用对象的执行。 Flask_apscheduler对APScheduler进行了集成&#xff0c;使得在Flask应用中可以简便…