无涯教程-进程 - 管道(Pipes)

news2024/11/19 4:35:16

管道是两个或多个相关进程之间的通信介质,它可以在一个进程内,也可以在子进程与父进程之间进行通信。

可以实时查看管道机制,例如用管道将水填充到某个容器(例如桶)中,然后取回某人(例如用杯子)。填充进程只不过是写入管道,而读取进程只不过是从管道中检索,这意味着一个输出(水)被输入到另一个(桶)。

Pipe with one
#include<unistd.h>

int pipe(int pipedes[2]);

该系统调用将创建用于单向通信的管道,即它创建两个描述符,第一个描述符连接以从管道读取,而另一个连接以写入管道。

描述符pipedes [0]用于读取,pipedes [1]用于写入,可以将任何写入pipedes [1]的内容从pipedes [0]中读取。

成功时此调用将返回零,失败时将返回-1,要知道失败的原因,请使用errno变量或perror()函数进行检查。

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

即使可以读写文件的基本操作,也必须在执行操作之前先打开文件,并在完成所需的操作后关闭文件。通常默认情况下为每个进程打开3个描述符,分别用于文件描述符0(标准输入– stdin)、1(标准输出– stdout)和2(标准错误– stderr)。

Read(读权限) - 4,Write(写权限) - 2和Execute (执行权限)-  1。

例如:八进制值(以0开头),0764表示所有者拥有读取,写入和执行权限,组拥有读取和写入权限,其他拥有读取权限。这也可以表示为S_IRWXU |。 S_IRGRP | S_IWGRP | S_IROTH,表示或操作为0700 | 0040 | 0020 | 0004→0764。

如果发生错误,此系统调用成功后将返回新的文件描述符ID和-1。可以使用errno变量或perror()函数确定错误原因。

#include<unistd.h>

int close(int fd)

上面的系统调用关闭已经打开的文件描述符,这意味着该文件不再使用,并且关联的资源可以由任何其他进程重用。该系统调用成功返回零,如果出错则返回-1。可以使用errno变量或perror()函数确定错误原因。

#include<unistd.h>

ssize_t read(int fd, void *buf, size_t count)

上面的系统调用是从指定的文件中读取文件描述符fd的参数,具有已分配内存(静态或动态)的适当缓冲区以及缓冲区的大小。

文件描述符ID用于标识相应的文件,该文件在调用open()或pipe()系统调用后返回,从文件读取之前,需要先打开文件。如果调用pipe()系统调用,它将自动打开。

要知道失败的原因,请使用errno变量或perror()函数进行检查。

#include<unistd.h>

ssize_t write(int fd, void *buf, size_t count)

上面的系统调用是使用文件描述符fd的参数,具有分配的内存(静态或动态)和缓冲区大小的适当缓冲区写入指定的文件。

范例程序

以下是一些示例程序。

示例程序1 -使用管道编写和读取两条消息的程序。

源代码:simplepipe.c

#include<stdio.h>
#include<unistd.h>

int main() {
   int pipefds[2];
   int returnstatus;
   char writemessages[2][20]={"Hi", "Hello"};
   char readmessage[20];
   returnstatus = pipe(pipefds);  #创建管道
   
   if (returnstatus == -1) {
      printf("Unable to create pipe\n");
      return 1;
   }
   
   printf("Writing to pipe - Message 1 is %s\n", writemessages[0]);
   write(pipefds[1], writemessages[0], sizeof(writemessages[0])); #向管道发送消息
   read(pipefds[0], readmessage, sizeof(readmessage)); #从管道中检索消息并将其写入标准输出
   printf("Reading from pipe – Message 1 is %s\n", readmessage);
   printf("Writing to pipe - Message 2 is %s\n", writemessages[0]);
   write(pipefds[1], writemessages[1], sizeof(writemessages[0])); #向管道发送另一条消息
   read(pipefds[0], readmessage, sizeof(readmessage));  #从管道中检索消息并将其写入标准输出
   printf("Reading from pipe – Message 2 is %s\n", readmessage);
   return 0;
}

注意-理想情况下,需要检查每个系统调用的返回状态。为了简化进程,不对所有calls进行检查。

汇编

gcc -o simplepipe simplepipe.c

执行/输出

Writing to pipe - Message 1 is Hi
Reading from pipe  Message 1 is Hi
Writing to pipe - Message 2 is Hi
Reading from pipe  Message 2 is Hell

示例程序2  -  使用父进程和子进程通过管道写入和读取两条消息的程序。

源代码:pipewithprocesses.c

#include<stdio.h>
#include<unistd.h>

int main() {
   int pipefds[2];
   int returnstatus;
   int pid;
   char writemessages[2][20]={"Hi", "Hello"};
   char readmessage[20];
   returnstatus = pipe(pipefds); #创建管道
   if (returnstatus == -1) {
      printf("Unable to create pipe\n");
      return 1;
   }
   pid = fork(); #创建一个子进程
   
   //Child process
   if (pid == 0) {
      read(pipefds[0], readmessage, sizeof(readmessage)); #子进程从管道中检索消息并将其写入标准输出
      printf("Child Process - Reading from pipe – Message 1 is %s\n", readmessage);
      read(pipefds[0], readmessage, sizeof(readmessage));
      printf("Child Process - Reading from pipe – Message 2 is %s\n", readmessage);
   } else { //Parent process
      printf("Parent Process - Writing to pipe - Message 1 is %s\n", writemessages[0]);
      write(pipefds[1], writemessages[0], sizeof(writemessages[0])); #父进程写入管道
      printf("Parent Process - Writing to pipe - Message 2 is %s\n", writemessages[1]);
      write(pipefds[1], writemessages[1], sizeof(writemessages[1]));
   }
   return 0;
}

汇编

gcc pipewithprocesses.c o pipewithprocesses

执行

Parent Process - Writing to pipe - Message 1 is Hi
Parent Process - Writing to pipe - Message 2 is Hello
Child Process - Reading from pipe  Message 1 is Hi
Child Process - Reading from pipe  Message 2 is Hello

双向通讯

管道通信仅被视为单向通信,即父进程写入而子进程读取,反之亦然,但不是两者都通信。但是如果父进程和子进程都需要同时写入和读取管道,该解决方案是使用管道的双向通信,需要两条管道来创建双向通信。

以下是实现双向通信的步骤-

步骤1   -  创建两个管道,第一个是父进程写,子进程读,比如pipe1。第二个是让子进程写,父进程读,例如pipe2。

步骤2   -  创建一个子进程。

步骤3   -  关闭不必要的一端,因为每次通信只需要一端。

步骤4   -  在父进程中关闭不需要的端,读取pipe1的端并写入pipe2的端。

步骤5   -  关闭子进程中不需要的一端,写入pipe1的一端,并读取pipe2的一端。

步骤6   -  根据需要执行通信。

Pipe with two

样例程序

示例程序1  -  使用管道实现双向通讯。

源代码:twowayspipe.c

#include<stdio.h>
#include<unistd.h>

int main() {
   int pipefds1[2], pipefds2[2];
   int returnstatus1, returnstatus2;
   int pid;
   char pipe1writemessage[20] = "Hi";
   char pipe2writemessage[20] = "Hello";
   char readmessage[20];
   returnstatus1 = pipe(pipefds1); #父进程创建管道1,子进程读取管道
   
   if (returnstatus1 == -1) {
      printf("Unable to create pipe 1\n");
      return 1;
   }
   returnstatus2 = pipe(pipefds2); #为要写入的子进程和要读取的父进程创建pipe2
   
   if (returnstatus2 == -1) {
      printf("Unable to create pipe 2\n");
      return 1;
   }
   pid = fork();
   
   if (pid != 0) //Parent process {
      close(pipefds1[0]); //Close the unwanted pipe1 read side    #从父级和子级关闭管道的多余末端
      close(pipefds2[1]); //Close the unwanted pipe2 write side
      printf("In Parent: Writing to pipe 1 – Message is %s\n", pipe1writemessage);
      write(pipefds1[1], pipe1writemessage, sizeof(pipe1writemessage));#编写消息的父进程和阅读并在屏幕上显示的子进程
      read(pipefds2[0], readmessage, sizeof(readmessage));
      printf("In Parent: Reading from pipe 2 – Message is %s\n", readmessage);
   } else { //child process
      close(pipefds1[1]); //Close the unwanted pipe1 write side
      close(pipefds2[0]); //Close the unwanted pipe2 read side
      read(pipefds1[0], readmessage, sizeof(readmessage));  #编写消息的子进程和读取和显示在屏幕上的父进程。
      printf("In Child: Reading from pipe 1 – Message is %s\n", readmessage);
      printf("In Child: Writing to pipe 2 – Message is %s\n", pipe2writemessage);
      write(pipefds2[1], pipe2writemessage, sizeof(pipe2writemessage));
   }
   return 0;
}

执行步骤

汇编

gcc twowayspipe.c o twowayspipe

执行

In Parent: Writing to pipe 1  Message is Hi
In Child: Reading from pipe 1  Message is Hi
In Child: Writing to pipe 2  Message is Hello
In Parent: Reading from pipe 2  Message is Hello

进程 - 管道(Pipes) - 无涯教程网无涯教程网提供管道是两个或多个相关进程之间的通信介质,它可以在一个进程内,也可以在子进程与父进...https://www.learnfk.com/process/inter-process-communication-pipes.html

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

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

相关文章

【无标题】jenkins消息模板(飞书)

这里写目录标题 Jenkins 安装的插件 发送消息到飞书预览 1 &#xff08;单Job&#xff09;预览 2 &#xff08;多Job&#xff0c;概览&#xff09; Jenkins 安装的插件 插件名称作用Rebuilder Rebuilder。 官方地址&#xff1a;https://plugins.jenkins.io/rebuild 安装方式&a…

软件研发CI/CD流水线图解

当谈到现代软件开发流程时&#xff0c;持续集成&#xff08;Continuous Integration&#xff0c;简称CI&#xff09;和持续交付&#xff08;Continuous Delivery&#xff0c;简称CD&#xff09;是两个关键的实践。它们旨在加速开发流程、提高软件质量&#xff0c;并使软件发布更…

java八股文面试[JVM]——元空间

JAVA8为什么要增加元空间 为什么要移除永久代&#xff1f; 知识来源&#xff1a; 【2023年面试】JVM8为什么要增加元空间_哔哩哔哩_bilibili

shopee开店后店铺怎么运营?这几点运营技巧要学会!

Shopee卖家开店后&#xff0c;这几点运营技巧要学会&#xff01; 1.Listing上架 产品在上架前&#xff0c;卖家要为主打产品需要精细化打造好文案和图片后再上传&#xff0c;尽量不要随意上架或者等到上架后再优化&#xff0c;避免浪费了新品最佳流量时期。 卖家可以从标题、…

【基于Arduino的仿生蚂蚁机器人】

【基于Arduino的仿生蚂蚁机器人】 1. 概述2. Arduino六足位移台–蚂蚁机器人3D模型3. 3D 打印零件4. 组装Arduino六足位移台5. Arduino蚂蚁机器人电路图6. 为Arduino Hexapod设计PCB7. 组装电路板8. 系统代码9. Arduino蚂蚁机器人安卓应用程序在本教程中,我将向您展示如何构建…

Total Uninstall | Windows 专业卸载清理工具

前言&#xff1a;Total Uninstall PC 专业卸载清理工具&#xff1a;彻底清除软件痕迹的神器 在日常使用电脑的过程中&#xff0c;我们常常需要安装和卸载各种软件。然而&#xff0c;传统的卸载方法往往并不能彻底清除软件的痕迹&#xff0c;使得电脑逐渐变慢或者出现各种问题。…

Idea常用快捷键--让你代码效率提升一倍(一)

一、代码编辑相关快捷键 1.单行复制(实现快速创建多个对象)CtrlD 2.空出下一行 ShiftEnter 3.单行注释快捷键 ctrl / 4.快速构建构造函数&#xff0c;setter&#xff0c;getter、toString方法 AltInsert 4.显示快速修复和操作的菜单 altenter 5.格式化代码&#xff1a;C…

leetcode 767. Reorganize String(重组字符串)

重新排列字符串s中的字母&#xff0c;使得任意两个相邻的字母都不相同。 思路&#xff1a; 让相邻字母不同&#xff0c;能想到的办法是先把相同的字母排列&#xff0c; 然后在相同字母的缝隙中插入另一种字母。 比如"aab", 先把"a a"排出来&#xff0c;再…

Python“牵手”拼多多商品列表数据,关键词搜索拼多多API接口数据,拼多多API接口申请指南

拼多多平台API接口是为开发电商类应用程序而设计的一套完整的、跨浏览器、跨平台的接口规范&#xff0c;拼多多API接口是指通过编程的方式&#xff0c;让开发者能够通过HTTP协议直接访问拼多多平台的数据&#xff0c;包括商品信息、店铺信息、物流信息等&#xff0c;从而实现拼…

ssm中小型企业财务管理系统源码和论文

ssm中小型企业财务管理系统源码和论文067 开发工具&#xff1a;idea 数据库mysql5.7 数据库链接工具&#xff1a;navcat,小海豚等 技术&#xff1a;ssm 1、研究目的意义 社会经济的迅速发展和科学技术的全面进步&#xff0c;计算机技术的飞速发展&#xff0c;以及计算机与…

开启网络安全量化时代丨Fortinet AI 驱动型安全运营方案让价值看得见

网络安全投资如何才能体现价值&#xff0c;一直都是困扰企业安全负责人的头等大事。这关系到企业何时进行网络安全产品的更新换代&#xff0c;又该如何判断是否应新增部署工具、人员或流程&#xff0c;以及已有投资是否值得……诸多关键问题。Fortinet与知名研究机构Enterprise…

python替换—Series.replace()与Series.str.replace()的区别及为何replace()无效的解决方法

文章目录 前言一、Series.replace()方法二、Series.str.replace()方法三、replace()与str.replace() 使用方法的区别四、常见的坑&#xff1a;python中replace方法不起作用 前言 在Pandas中&#xff0c;Series是一个由一维数组表示的DataFrame列&#xff0c;而replace和str.re…

借助流程引擎表单,一举创造高效率办公流程化管理!

办公流程化管理&#xff0c;是很多企业的追求目标和发展愿景。如何实现这一目标&#xff1f;如何让企业内部的数据更好地实现价值&#xff0c;创造辉煌前景&#xff1f;借助流程引擎表单&#xff0c;可以助力企业实现高效率办公&#xff0c;让每一个表单制作场景更为顺畅和高效…

Redis 重写 AOF 日志期间,主进程可以正常处理命令吗?

重写 AOF 日志的过程是怎样的&#xff1f; Redis 的重写 AOF 过程是由后台子进程 bgrewriteaof 来完成的&#xff0c;这么做有以下两个好处。 子进程进行 AOF 重写期间&#xff0c;主进程可以继续处理命令请求&#xff0c;从而避免阻塞主进程子进程带有主进程的数据副本。这里…

Verilog 实现状态机自动售卖机

Verilog 实现状态机自动售卖机 教学视频&#xff1a;https://www.bilibili.com/video/BV1Ve411x75W?p33&spm_id_frompageDriver&vd_source19ae31dff4056e52d2729a4ca212602b 功能需求 使用1元、2元、5元面值的纸币进行支付&#xff0c;获取6元的物品&#xff0c;不设…

天津大数据培训机构 全面分析大数据怎么样?

数字化和信息化时代的发展&#xff0c;推动了大数据的高速发展&#xff0c;在这个大数据时代的浪潮中&#xff0c;越来越多人加入到大数据培训&#xff0c;都希望在大数据培训机构中学习最前沿的知识。 大数据人才行业需求 大数据行业近年来仍然呈现出增长态势&#xff0c;并…

Linux centos7 bash编程小训练

训练要求&#xff1a; 求比一个数小的最大回文数 知识点&#xff1a; 一个数字正读反读都一样&#xff0c;我们称为回文数&#xff0c;如5、11、55、121、222等。 我们训练用bash编写一个小程序&#xff0c;由我们标准输入一个整数&#xff0c;计算机将显示出一个比这个数小…

相对位置关系对排斥能的影响

( A, B )---3*30*2---( 1, 0 )( 0, 1 ) 让网络的输入只有3个节点&#xff0c;AB训练集各由5张二值化的图片组成&#xff0c;让A中有2个1&#xff0c;B中有1个1&#xff0c;且不重合&#xff0c;排列组合&#xff0c;统计迭代次数并排序。 其中有5组数据 构造平均列A 构造平均…

SPI总线协议

简述 SPI协议是一种芯片与芯片之间的通讯&#xff0c;全称是Serial Peripheral Interface SPI通讯采用一主多从模式&#xff0c;产生时钟的一侧称为主机&#xff0c;另一侧称为从机。只有一个主机&#xff08;一般来说可以是微控制器/MCU&#xff09;&#xff0c;但是可以有一…

不要“妖魔化”外包,看完我悟了......

在IT圈子里&#xff0c;经常能看到一个很有意思的现象&#xff0c;对于外包工作&#xff0c;不同看法的网友们常常吵的不可开交。 新人程序员试图从“前辈”的经验中找出答案&#xff0c;以作为自己要不要去外包公司的参考&#xff0c;但往往刷帖无数&#xff0c;却依旧举棋不…