管道的用法

一、fork 的用法

fork 返回值 c++

在C++中,fork 是一个来自 Unix/Linux 系统的系统调用,用于创建一个与现有进程几乎完全相同的新进程。fork 的主要特点是它会返回两次,一次返回在父进程中,一次返回在子进程中。在父进程中,fork 返回新创建子进程的进程ID;而在子进程中,fork 返回0。如果fork失败,则在父进程中返回-1,并设置errno

以下是一个简单的C++示例,演示如何使用 fork

生成的结果如下:

二、什么是匿名管道 

匿名管道是linux中一种非常古老进程间通信方式,本质上就是一个内存级的文件。

一般用于父子进程间通信。概念上就是父进程与子进程共同使用一个管道文件来传输数据。

虽然父子进程都有对管道的读和写功能,但在使用时只能读或者写,因此管道是单向通信,半双工模式。

三.如何使用匿名管道

(一).pipe原理

参数是长度为2的整形数组,pipefd[0]代表读端文件描述符,pipefd[1]代表写端文件描述符。

返回值是int,创建成功返回0,失败返回-1,同时记录进errno。 

pipe的使用原理上,就是首先父进程创建一个管道文件,但同时赋予管道文件两个文件描述符。

一个是以读方式打开即pipefd[0],另一个是以写方式打开即pipefd[1]。

(二).pipe使用
以下面代码为例:

父进程使用write接口将字符串给管道,子进程从管道中接收字符串并打印。

同时,子进程的read系统接口会阻塞,直到父进程往管道中写完数据,read一次性将此时管道内数据读取完并清空管道。

当父进程关闭管道后,若管道中还有数据时read函数会一次性读取完并在下一次读取时返回0,没有数据时直接返回0。
 
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<unistd.h>
  4 #include<string>
  5 #include<assert.h>
  6 using namespace std;
  7 int main()
  8 {
  9   int pfd[2] = { 0 };
 10   int ret = pipe(pfd);
 11   assert(ret == 0);
 12   printf("main:%d\n",getpid());
 13   pid_t id = fork();
 14   assert(id >= 0);
 15  if (id < 0)
 16   {
 17         printf("Failed to fork\n");
 18         return -1;
 19   }
 20  else if(id == 0)
 21   {
 22          close(pfd[1]);
 23           //关闭写端
 24          char GetStr[1024] = { 0 };
 25           ssize_t i = read(pfd[0], GetStr, sizeof GetStr);//接收数据
 26          GetStr[i] = '\0';
 27          cout << GetStr << endl;
 28         printf("son:%d\n",getpid());
 29         //cout << getpid()<< endl;
 30          exit(0);
 31    }
 32   else
 33   {
 34         printf("parent:%d\n",getpid());
 35 
 36   }
 37      //父进程
 38   printf("main second:%d\n",getpid());
 39   close(pfd[0]);
 40   char str[1024] = "hello world";
 41   write(pfd[1], str, sizeof str);//发送数据
 42 
 43   return 0;
 44 }

输出结果如下:

四、命名管道 

1.什么是命名管道?

匿名管道应用的一个限制就是只能在具有共同祖先(具有亲缘关系)的进程间通信。如果我们想在不相关的进程之间交换数据,可以使用FIFO文件来做这项工作,它经常被称为命名管道。命名管道是一种特殊类型的文件。

2.怎么创建命名管道(函数)?

命名管道可以从命令行上创建,命令行方法是使用下面这个命令:

mkfifo filename

命名管道也可以从程序里创建,相关函数有 :

#include <sys/types.h>

#include <sys/stat.h>

int mkfifo(const char *filename,mode_t mode);

filename:命名管道的名字

mode:权限值

返回值:成功返回0,失败返回-1

3.命名管道的打开规则

如果当前打开操作是为读而打开FIFO时:

  • O_NONBLOCK (disable):阻塞直到有相应进程为写而打开该FIFO
  • O_NONBLOCK (enable):立刻返回成功

如果当前打开操作是为写而打开FIFO时 :

  • O_NONBLOCK (disable):阻塞直到有相应进程为读而打开该FIFO
  • O_NONBLOCK (enable):立刻返回失败,错误码为ENXIO

4.怎么使用命名管道?命名管道有什么用?(例子)

processA.cc
  1 #include "fifo.h"
  2 using namespace std;
  3 bool MakeFifo()
  4 {
  5     int n = mkfifo(FIFONAME, 0644);
  6     if(n < 0)
  7     {
  8         cout << "mkfifo fail" << endl;
  9         return false;
 10     }
 11     return true;
 12 }
 13 
 14 int main()
 15 {
 16     //创建命名管道
 17     if(!MakeFifo())
 18     {
 19         cerr << "mkfifo fail" << endl;
 20         return 1;
 21     }
 22     //打开fifo文件写
 23     int wfd = open(FIFONAME, O_WRONLY);
 24     if(wfd < 0)
 25     {
 26         cerr << "open fifo fail" << endl;
 27         return 2;
 28     }
 29     cout << "Process A is sending a message to process B" << endl;
 30     char message[] = "i am process A";
 31     write(wfd, message, sizeof(message));
 32 
 33     return 0;
 34 } 


  1 #include "fifo.h"
  2 using namespace std;
  3  
  4 int main()
  5 {
  6     //打开fifo文件写
  7     int rfd = open(FIFONAME, O_RDONLY);
  8     if(rfd < 0)
  9     {
 10         cerr << "open fifo fail" << endl;
 11         return 2;
 12     }
 13     cout << "receives messages from process A: ";
 14     char message[30];
 15     read(rfd, message, sizeof(message));
 16 
 17     cout << message << endl;
 18 
 19     return 0;
 20 }
 fifo.h

 1 #include <sys/types.h>
  2 #include <sys/stat.h>
  3 #include <iostream>
  4 #include <cassert>
  5 #include <fcntl.h>
  6 #include <unistd.h>
  7 
  8 #define FIFONAME  "fifo"

五、匿名管道和命名管道的区别  

  • 匿名管道由pipe函数创建并打开。
  • 命名管道由mkfifo函数创建,打开用open
  • FIFO(命名管道)与pipe(匿名管道)之间唯一的区别在它们创建与打开的方式不同,一但这些工作完成之后,它们具有相同的语义

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

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

相关文章

Python快速入门系列-10(Python进阶与扩展)

第十章:Python进阶与扩展 10.1 Python与其他语言的整合10.1.1 使用Python的C API示例:使用C API创建一个简单的Python扩展10.1.2 使用Cython加速Python代码示例:使用Cython编写一个快速的矩阵乘法函数10.1.3 使用SWIG创建接口示例:使用SWIG为C++类生成Python接口10.2 Pytho…

网络安全 | 什么是云安全?

关注WX&#xff1a;CodingTechWork 云安全-介绍 云安全是为了解决企业安全所面临的外部和内部威胁&#xff0c;它是一组程序和技术的集合。企业在实施其数字化转型策略&#xff0c;并将各种云端工具和服务纳入企业基础架构中时&#xff0c;需要云安全保障业务顺利进行。 云计…

957: 逆置单链表

学习版 【C语言】 #include<iostream> using namespace std; typedef struct LNode {char data;struct LNode* next;LNode(char x) :data(x), next(nullptr) {} }LNode; void creatlist(LNode *&L) {int n;char e;cin >> n;LNode* p1, * p2;p1 L;for (int i…

Android 高德地图

1.获取Key 进入高德开放平台控制台&#xff0c;创建一个新应用。在创建的应用上点击"添加key"按钮&#xff0c;在弹出的对话框中&#xff0c;依次输入key名称&#xff0c;选择服务平台为“Android平台”&#xff0c;输入发布版安全码 SHA1、以及 Package。 获取 S…

Elasticsearch 压测实践总结

背景 搜索、ES运维场景离不开压力测试。 1.宿主机层面变更&#xff1a;参数调优 & 配置调整 & 硬件升级2.集群层面变更&#xff1a;参数调优3.索引层面变更&#xff1a;mapping调整 当然还有使用层面变更&#xff0c;使用API调优&#xff08;不属于该文章的讨论范围…

Python 之 Fastapi 框架学习

依赖安装 Fastapi 有版本要求&#xff0c;需要的 Python 版本至少是 Python 3.8&#xff08;不要犟&#xff0c;按照版本要求来&#xff0c;我最先也是在我 Python3.6 上装的&#xff0c;果不其然跑不起来&#xff09;&#xff0c;幸好我 Win7 老古董能支持的 Python 最高版本…

Python爬虫详解:原理、常用库与实战案例

前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff1a;https://www.captainbed.cn/z ChatGPT体验地址 文章目录 前言引言&#xff1a;一、爬虫原理1. HTTP请求与响应过程2. 常用爬虫技术 二、P…

《自动机理论、语言和计算导论》阅读笔记:p115-p138

《自动机理论、语言和计算导论》学习第 6 天&#xff0c;p115-p138 总结&#xff0c;总计 24 页。 一、技术总结 1.associativity and comutativity (1)commutativity(交换性): Commutativity is the property of an operator that says we can switch the order of its ope…

二分答案跳石头游戏

步骤&#xff1a; 输入&#xff1a; 用户输入了三个整数&#xff0c;分别表示石头的总长度l&#xff0c;石头的数量n&#xff0c;以及最多可以撤去的石头数量m。 初始化石头位置数组&#xff1a; 创建一个长度为n2的数组arr&#xff0c;用于存储每块石头的位置。数组的第一项…

【JavaWeb】Day29.SpringBootWeb请求响应——请求(二)

请求响应 4.数组集合参数 数组集合参数的使用场景&#xff1a;在HTML的表单中&#xff0c;有一个表单项是支持多选的(复选框)&#xff0c;可以提交选择的多个值。 4.1 数组 数组参数&#xff1a;请求参数名与形参数组名称相同且请求参数为多个&#xff0c;定义数组类型形参即…

TCP 三次握手

在TCP协议中&#xff0c;初始化ISN是TCP连接建立过程中客户端用来初始化序列号的一个值。这个值在TCP三次握手的第一步中被客户端放入了SYN数据包的序列号字段中。 **第一步&#xff1a;**客户端会发送一个数据包。包内的Flags的 Syn字段被置位从而表明它是一个Syn数据包。 此…

PCB设计中的EMC技术

除了元器件的选择和电路设计之外&#xff0c;良好的印制电路板&#xff08;PCB&#xff09;设计在电磁兼容性中也是一个非常重要的因素。PCB EMC设计的关键&#xff0c;是尽可能减小回流面积&#xff0c;让回流路径按照设计的方向流动。最常见返回电流问题来自于参考平面的裂缝…

计算机笔记(3)续20个

41.WWW浏览器和Web服务器都遵循http协议 42.NTSC制式30帧/s 44.三种制式电视&#xff1a;NTSC&#xff0c;PAL&#xff0c;SECAM 45.IP&#xff0c;子网掩码白话文简述&#xff1a; A类地址&#xff1a;取值范围0-127&#xff08;四段数字&#xff08;127.0.0.0&#xff09…

vivado 串行矢量格式 (SVF) 文件编程

串行矢量格式 (SVF) 文件编程 注释 &#xff1a; 串行矢量格式 (SVF) 编程在 Versal ™ 器件上不受支持。 对 FPGA 和配置存储器器件进行编程的另一种方法是通过使用串行矢量格式 (SVF) 文件来执行编程。通过 Vivado Design Suite 和 Vivado Lab Edition 生成的 SVF …

商家转账到零钱开通不了解决方案

商家转账到零钱是什么&#xff1f; 【商家转账到零钱】可以说是【企业付款到零钱】的升级版&#xff0c;商家转账到零钱可以为商户提供同时向多个用户微信零钱转账的能力&#xff0c;支持分销返佣、佣金报酬、企业报销、企业补贴、服务款项、采购货款等自动向用户转账的场景。…

dhcp中继代理

不同过路由器分配ip了&#xff0c;通过一台服务器来代替&#xff0c;路由器充当中继代理功能&#xff0c;如下图 服务器地址&#xff1a;172.10.1.1/24 配置流程&#xff1a; 1.使能dhcp功能 2.各个接口网关地址&#xff0c;配置dhcp中继功能 dhcp select relay &#xff0…

移动WEB开发之rem适配布局

一、rem 基础 rem 单位 rem (root em)是一个相对单位&#xff0c;类似于em&#xff0c;em是父元素字体大小。不同的是rem的基准是相对于html元素的字体大小。比如&#xff0c;根元素&#xff08;html&#xff09;设置font-size12px; 非根元素设置width:2rem; 则换成px表示就是2…

微服务连接不上rabbitmq解决

1.把端口port: 15672改成port&#xff1a;5672 2&#xff1a;virtual-host: my_vhost一定对应上

基于AI智能识别技术的智慧展览馆视频监管方案设计

一、建设背景 随着科技的不断进步和社会安全需求的日益增长&#xff0c;展览馆作为展示文化、艺术和科技成果的重要场所&#xff0c;其安全监控系统的智能化升级已成为当务之急。为此&#xff0c;旭帆科技&#xff08;TSINGSEE青犀&#xff09;基于视频智能分析技术推出了展览…

Linux网络协议栈从应用层到内核层④

文章目录 1、网卡接受数据2、网络设备层接收数据3、ip层接受数据4、tcp层接受数据5、上层应用读取数据6、数据从网卡到应用层的整体流程 1、网卡接受数据 当网卡收到数据时&#xff0c;会触发一个中断&#xff0c;然后就会调用对应的中断处理函数&#xff0c;再做进一步处理。…