Linux -- 进程间通信、初识匿名管道

目录

进程间通信

什么是进程间通信

进程间通信的一般规律

前言:

管道

代码预准备:

如何创建管道 -- pipe 函数

参数:

返回值:

wait 函数

参数:

验证管道的运行:

源文件 test.c :

makefile 文件:

 运行结果:


进程间通信

什么是进程间通信

进程间通信(Inter-Process Communication, IPC)是操作系统中非常重要的一个概念,它指的是不同进程之间进行数据交换或者传递消息的机制

进程间通信的主要原因和目的是:

  1. 资源共享不同的进程可能需要访问相同的资源或数据,例如文件、数据库等。通过IPC,可以实现对这些共享资源的有效管理和同步访问。

  2. 任务协作:在很多情况下,一个复杂的任务可能被分解为多个子任务,由不同的进程来执行。为了完成整个任务,这些进程之间需要相互通信,以协调它们的工作流程。

  3. 提高效率:对于一些计算密集型的任务,可以通过将工作分配给多个进程来并行处理,从而加速任务的完成。这时就需要有效的通信机制来保证各部分工作的正确性与一致性。

  4.  模块化设计:软件开发时采用模块化的设计思想,即将程序划分为相对独立但又能相互作用的功能单元(即进程)。这样做不仅有利于维护,而且也使得系统更加灵活可扩展。良好的IPC支持能够促进这种架构模式的应用。

  5. 跨网络服务调用:随着分布式系统的普及,在不同主机上的进程也需要能够互相通信。这涉及到更高级别的IPC形式,如RPC (Remote Procedure Call) 等技术。

进程间通信的一般规律

让不同的进程看到同一份资源!!!

前言:

假设现在有A、B进程,在A进程中开辟一块空间并写入数据,让 B 进程去 A 进程的这块空间读取数据,虽然确实让不同的进程看到了同一份资源,但是破坏了进程的独立性。

所以进程间通信需要有交换数据的空间,且这块空间不能由通信双方任何一个提供,那么这块空间只能由操作系统提供。

我们回顾一下父子进程,假设父进程对同一个文件分别用读方式和写方式打开,父进程将会得到两个文件描述符对象。

为什么对同一个文件分别用读方式打开和写方式打开,会创建两个文件描述符对象?

当你使用读取模式(例如 open("file.txt", "r"))和写入模式(例如 open("file.txt", "w"))分别打开同一个文件时,操作系统会为每次打开操作分配一个独立的文件描述符。这样做有几个原因:

  1. 独立性:每个文件描述符代表了对文件的一个独立访问路径。这意味着你可以同时从一个文件描述符读取数据,而从另一个文件描述符写入数据,即使它们指向的是同一个物理文件。这种独立性允许更灵活地处理文件。

  2. 位置指针:每个文件描述符都有自己的文件偏移量或位置指针。当你通过不同的文件描述符读写文件时,每个描述符的位置指针可以独立移动。这样,在进行多线程或多进程操作时,各个进程/线程可以安全地在不同位置上工作而不互相干扰。

  3. 权限控制:以不同模式打开文件提供了对文件的不同级别的访问权限。比如,只读模式下你只能读取文件内容,而在写入模式下还可以修改文件。拥有两个文件描述符意味着可以根据需要选择适当的访问级别,同时也增加了安全性,因为不需要给所有操作都赋予完全相同的权限。

  4. 性能与资源管理:尽管是同一份文件,但根据具体的操作需求(如顺序读取、随机写入等),操作系统可能采取不同的策略来优化I/O性能。此外,维护多个文件描述符也便于系统更好地跟踪哪些程序正在使用该文件,并且有助于实现诸如引用计数这样的机制,从而有效地管理文件相关的系统资源。

总之,虽然这两个文件描述符对应于同一物理文件,但是它们各自保持了自己的状态信息,这使得在同一时间内能够执行更加复杂的并发操作,同时也增强了系统的灵活性和安全性。

父进程得到两个文件描述符对象之后,我们创建子进程,子进程继承父进程的文件描述符表,父子进程指向同一个文件和缓冲区!这也就实现了父子进程看到同一份资源,就可以实现进程间通信!

管道

从前言中就可以看出,管道的本质是文件!

在 Linux 中,管道(pipe)是一种进程间通信(IPC, Inter-Process Communication)的机制,它允许一个进程的输出直接作为另一个进程的输入。

管道可以看作是连接两个或多个命令的数据流通道,它使得数据可以在不同的程序之间流动而不需要通过临时文件。

标准的管道是单向的,即数据只能从写端流向读端。

匿名管道: 

在前言中,父进程和子进程的文件的读端和写端都是打开的,为了符合管道是单向的,我们可以选择让 父进程作为写端,子进程作为读端 或者 父进程作为读端、子进程作为写端!

如下图,我们让父进程作为写端,子进程作为读端:

代码预准备:

如何创建管道 -- pipe 函数

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

该函数用于创建一个匿名管道

参数:

pipefd:这是一个指向两个整数的指针。pipe() 成功后,这两个整数会被设置为新创建的管道的读端和写端的文件描述符。读端通常为 fd[0],写端通常为 fd[1]

返回值:

  • 它在成功时返回 0,并且通过其参数(一个包含两个整数的数组)来传递两个文件描述符;
  • 如果调用失败,pipe() 会返回-1,并设置全局变量 errno 来指示具体的错误原因。

wait 函数

#include <sys/types.h>
#include <sys/wait.h>pid_t wait(int *status);

wait() 函数是 Unix 和 Linux 系统中用于进程控制的一个重要函数。它允许一个进程(通常是父进程)等待其子进程结束,并获取子进程的退出状态wait() 函数会阻塞调用者,直到至少有一个子进程终止或接收到一个信号。

参数:

status:这是一个指向整数的指针,用来存储子进程的退出状态信息如果不需要这个信息,可以传递 NULL

返回值:

  • 如果有子进程成功终止,则返回该子进程的 PID;
  • 如果没有子进程或者所有子进程都还在运行,wait() 将一直阻塞,直到至少有一个子进程终止。
  • 如果发生错误(如被信号中断),则返回-1,并设置 errno

验证管道的运行:

源文件 test.c :

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>void writer(int wfd)
{const char *str="hello father,I am child";char buffer[128];int cnt=0;pid_t pid=getpid();//获得进程pidwhile(1){//向缓冲区里写入内容snprintf(buffer,sizeof(buffer),"message:%s,pid:%d,count:%d\n",str,pid,cnt);//把缓冲区里的内容写入到管道write(wfd,buffer,sizeof(buffer));cnt++;sleep(1);}
}void reader(int rfd)
{char buffer[128];while(1){//读取管道里的内容ssize_t n=read(rfd,buffer,sizeof(buffer)-1);printf("father get a message: %s",buffer);}
}int main()
{int pipefd[2];int n=pipe(pipefd);if(n<0){return 1;}printf("%d %d\n",pipefd[0],pipefd[1]);pid_t id=fork();if(id==0){//子进程创建成功//关闭读端close(pipefd[0]);writer(pipefd[1]);//写exit(0);}//父进程关闭写端close(pipefd[1]);reader(pipefd[0]);//读wait(NULL);return 0;
}

makefile 文件:

testpipe:test.cgcc -o $@ $^.PHONY:clean
clean:rm -f testpipe

 运行结果:

从下面的运行结果可以看出,父进程接收到了子进程写的数据:

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

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

相关文章

独孤思维:新学员副业一周出单

所谓的一万小时定律。 即在某个技能上面&#xff0c;花费超过1万小时。 如果每天刻意练习1小时&#xff0c;则需要30年。 可行吗&#xff1f; 极难。 所以不要过分迷恋这种定律。 对于我们普通人而言&#xff0c;可以训练一个月或者三个月&#xff0c;即可掌握某项技能。…

深入解析:Linux tcpdump命令在网络流量分析中的实战应用

tcpdump是一个强大的命令行工具&#xff0c;用于捕获和分析TCP、UDP、ICMP等协议的网络流量。 功能与用途 捕获网络流量&#xff1a;tcpdump可以捕获和显示来自本地计算机或通过网络传输的数据包&#xff0c;提供有关数据包的详细信息&#xff0c;如源和目的IP地址、端口号、…

Python正则表达式(re模块)的正确匹配详解

基本匹配及一些符号的特定含义 正则表达式是用于处理文本的强大工具&#xff0c;在Python中通过 re 模块来使用。 基本匹配 - 首先要导入 re 模块。例如&#xff0c;要在字符串中查找简单的单词 apple &#xff0c;可以这样写&#xff1a; import re text "I have an a…

flutter集成极光推送

一、简述 极光推送&#xff0c;英文简称 JPush&#xff0c;免费的第三方消息推送服务&#xff0c;官方也推出众多平台的SDK以及插件。 参考链接 名称地址客户端集成插件客户端集成插件 - 极光文档 二、操作步骤 2.1 添加插件 flutter项目中集成官方提供的 极光推送flutte…

能源管理系统

一、介绍 基于SpringCloud的能管管理系统-能源管理平台源码-能源在线监测平台-双碳平台源码-SpringCloud全家桶-能管管理系统源码 二、软件架构 二、功能介绍 三、数字大屏展示 四、数据采集原理 五、软件截图

小渡Al论文写作:50个GPT学术指令——1天搞定1篇论文

选题与研究方向 假设你是某高校某专业的教授&#xff0c;请根据我感兴趣的研究方向&#xff0c;为我提供10个新颖且有研究意义的论文选题。我对某个选题感兴趣&#xff0c;请列举几个该领域当前的研究热点和争议点供我选择。假设我是某专业本科生/研究生&#xff0c;请为我提供…

springboot集成pdfbox解析pdf文件

springboot集成pdfbox解析pdf文件 1、引入依赖2、获取PDF文件3、获取需要的字段信息4、获取多字段时&#xff0c;步骤3需要优化&#xff0c;以下为优化后代码 1、引入依赖 <dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</a…

iconfont图标放置在某个元素的最右边

在网页设计中&#xff0c;如果你想要将iconfont图标放置在某个元素的最右边&#xff0c;你可以通过CSS来实现这个布局。以下是一些基本的CSS代码示例&#xff0c;它们可以帮助你根据不同的布局需求将图标放置在最右边&#xff1a; 内联元素&#xff08;如<span>&#xff…

perl读取目录,写入文件

perl读取目录&#xff0c;写入文件 此脚本有两个输入参数&#xff0c;第一个参数为需要打印的文件目录&#xff0c;第二个参数为打印后的文件名&#xff1b; 该脚本名称为out_file_full_path #!/bin/perluse 5.010; my $dir $ARGV[0]; # 此为第一个参数&#xff1b; opendi…

Unreal Engine5安装Niagara UI Renderer插件

系列文章目录 文章目录 系列文章目录前言一、如何下载安装Niagara UI Renderer插件 前言 在2024.10.24号的今天发现unreal engine官网已经没有虚幻商城了&#xff0c;取而代之的是FAB ‌虚幻商城已经停止运营&#xff0c;Epic Games推出了新的数字资产商店FAB。‌ Epic Games…

Python URL编码

在 Python 中&#xff0c;可以使用 urllib.parse模块对 URL 进行编码。 一、依赖安装 pip install urllib 二、URL编码 from urllib.parse import quoteurl rhttps://myshop.com/shop/shopList?query query {"id":14,"pageSize":10,"pageNum&quo…

【论文+源码】基于SSM+VUE的大学生兼职管理系统

创建一个大学生兼职管理系统&#xff0c;结合 SSM&#xff08;Spring Spring MVC MyBatis&#xff09;框架和 Vue.js 前端框架&#xff0c;可以分为几个主要步骤来实现。 第一部分&#xff1a;环境准备 1. 开发环境准备 Java JDK&#xff1a;确保已安装 Java 8 或更高版本。…

2024软考网络工程师笔记 - 第8章.网络安全

文章目录 网络安全基础1️⃣网络安全威胁类型2️⃣网络攻击类型3️⃣安全目标与技术 &#x1f551;现代加密技术1️⃣私钥密码/对称密码体制2️⃣对称加密算法总结3️⃣公钥密码/非对称密码4️⃣混合密码5️⃣国产加密算法 - SM 系列6️⃣认证7️⃣基于公钥的认证 &#x1f552…

从0开始深度学习(19)——参数管理

在选择了模型架构&#xff0c;并设置了超参数之后&#xff0c;就进入了训练阶段&#xff0c;此时&#xff0c;我们的目标是找到使损失函数最小化的模型参数值。 经过训练后&#xff0c;我们将需要使用这些参数来做出未来的预测。 此外&#xff0c;有时我们希望提取参数&#xf…

电子商务类型

常见电子商务类型及其代表性的例子&#xff1a; B2B&#xff08;Business to Business&#xff09; 定义&#xff1a;B2B 模式是指企业与企业之间的商业交易。在这种模式下&#xff0c;企业通过电子商务平台相互提供产品或服务。 特点&#xff1a; 大宗交易&#xff1a;通常…

数据结构 ——— 顺序表和链表的区别以及各自的优缺点

目录 顺序表和链表的区别 一、存储空间上 二、下标的随机访问 三、任意位置插入或者删除元素 四、添加数据 五、应用场景 六、缓存利用率 顺序表和链表的优缺点 顺序表的缺点 链表的优点&#xff08;和顺序表的缺点对应&#xff09; 顺序表的优点 链表的缺点&#…

背包九讲——完全背包问题

目录 完全背包问题 问题定义 动态规划解法 状态转移方程 初始化 遍历顺序 三种解法&#xff1a; 朴素版——枚举k 进阶版——dp正推&#xff08;一维滚动数组&#xff09; 背包问题第三讲——完全背包问题 背包问题是一类经典的组合优化问题&#xff0c;通常涉及在限定…

简介openwrt系统下/etc/config/network文件生成过程

openwrt的network文件&#xff0c;或者说在/etc/config下的文件&#xff0c;都是动态生成的。 脚本的函数定义在package/base-files/files/lib/functions中&#xff0c;有以下几个文件&#xff1a; libraSVN:~/Wang_SP4/openwrt-d03dc49/package/base-files/files/lib/functi…

【Linux笔记】Linux命令与使用

博文将不断学习补充 学习参考博文&#xff1a; Linux命令大全&#xff1a;掌握常用命令&#xff0c;轻松使用Linux操作系统-CSDN博客 文件或目录操作命令 zip # zip是使用最多的文档压缩格式 # 方便跨平台使用&#xff0c;但是压缩率不是很高 zip指令未安装 安装zip yum ins…

python实战项目47:Selenium采集百度股市通数据

python实战项目47:Selenium采集百度股市通数据 一、思路分析二、完整代码一、思路分析 这里以获取百度股市通股评下的投票数据为例,页面中的其他数据同理。由于此页面数据是js动态加载的,所以采用Selenium获取数据。思路很简单,通过Selenium打开页面,然后定位到“股评”选…