进程间通信学习笔记(有名管道和无名管道)

进程间通信方式:

  • 无名管道(pipe)
  • 有名管道(fifo)
  • 信号(signal)
  • 共享内存(mmap)
  • 套接字(socket)

 无名管道:

        在内核里面开辟一片内存,进程1和进程2都可以通过这片内存进行通信

无名管道特点:
  • 只能用于具有亲缘关系的进程之间的通信(比如父子进程、兄弟进程)
  • 单工的通信模式,具有固定的读端和写端(只能一个进程写、一个进程读,不能反过来)
  • 无名管道创建时会返回两个文件描述符,分别用于读写管道(一个进程只能用一个描述符,因为是单工通信)
无名管道创建-pipe
#include <unistd.h>
int pipe(int pfd[2]);
  • 成功时返回0,失败时返回EOF
  • pfd包含两个元素的整形数组,用来保存文件描述符
  • pfd[0]用于读管道;pfd[1]用于写管道

示例代码:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{int pfd[2];int re;char buf[20] = {0};__pid_t pid;re = pipe(pfd);if(re < 0){perror("pipe");return 0;}printf("%d,%d\n",pfd[0],pfd[1]);pid = fork();if(pid < 0){perror("fork");return 0;}else if(pid == 0)//子进程{close(pfd[0]);while (1){strcpy(buf,"hahahahhahah");write(pfd[1],buf,strlen(buf));sleep(1);}}else // 父进程{close(pfd[1]);while (1){re = read(pfd[0],buf,20);if(re > 0){printf("red pipe=%s\n",buf);}} }
}

 运行结果:

创建两个子线程,两个子线程对管道就行写,一个父进程对管道进行读,示例代码:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{int pfd[2];int re,i;char buf[40] = {0};__pid_t pid;re = pipe(pfd);if(re < 0){perror("pipe");return 0;}printf("%d,%d\n",pfd[0],pfd[1]);for(i = 0;i < 2;i++){pid = fork();if(pid < 0){perror("fork");return 0;}else if(pid > 0)// 父进程{}else //子进程{break; }}if (i == 2)//父进程执行到这里{close(pfd[1]);while (1){memset(buf,0,40);re = read(pfd[0],buf,20);if(re > 0){printf("%s\n",buf);}}return 0;}if (i == 1){close(pfd[0]);while (1){strcpy(buf,"this is 2 process");write(pfd[1],buf,strlen(buf));usleep(930000);}return 0;}if (i == 0){close(pfd[0]);while (1){strcpy(buf,"this is 1 process");write(pfd[1],buf,strlen(buf));sleep(1);}return 0;}
}

 运行结果:

无名管道读写特性:

1.读管道:

(1)管道中有数据,read返回实际读到的字节数

(2)管道中无数据:

  • 管道写端被全部关闭(就是读写全关闭),read返回0(好像读到文件结尾)
  • 写端没有全部被关闭(就是把读关闭,没有关闭写),read阻塞等待(不就的将来可能有数据抵达,此时让出cpu)

2.写管道:

(1)管道读端全部被关闭(就是读写全关闭),进程异常终止(也可以使用SIGPIPE信号,使进程不终止)

(2)管道读端没有全部关闭(就是把写关闭,没有关闭读):

  • 管道已满,write阻塞(管道是64k)
  • 管道未满,write将数据写入,并返回实际写入的字节数

有名管道(fifo)特点:

  • 有名管道可以使非亲缘的两个进程互相通信
  • 通过路径名称来操作,在文件系统中可见,但内容存放在内存中(不是磁盘文件)
  • 文件IO来操作有名管道
  • 遵循先进先出规则
  • 不支持leek操作
  • 单工读写
有名管道创建-mkfifo:
#include <unistd.h>
#include <fcntl.h>
int mkfifo(const char *path,mode_t mode);
  • 成功时返回0,失败时返回EOF
  • path创建的管道文件路径
  • mode管道文件的权限,如666

示例代码:

向文件写:

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
int main()
{int re;int fd;char buf[32];re = mkfifo("./myfifo",0666);if (re < 0){perror("mkfifo");// return 0;}fd = open("./myfifo",O_WRONLY);if (fd < 0){perror("open");return 0;}while (1){fgets(buf,32,stdin);write(fd,buf,strlen(buf));}
}

 向文件读:

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
int main()
{int re;int fd;char buf[32];fd = open("./myfifo",O_RDONLY);if (fd < 0){perror("open");// return 0;}while (1){re = read(fd,buf,32);if (re > 0){printf("read fifo=%s\n",buf);}else{exit(0);}}
}

运行结果:

open函数四种状态

open(const char *path,O_RDONLY);

open(const char *path,O_RDONLY|O_NONBLOCK);

open(const char *path,O_WRONLY);

open(const char *path,O_WRONLY|O_NONBLOCK); 

 注意事项
  1. 就是程序不能以O_RDWR(读写)模式打开FIFO文件进行读写操作,而其行为也未明确定义,因为如一个管道以读/写方式打开,进程可以读回自己的输出,同时我们通常使用FIFO只是为了单向的传递数据
  2. 第二个参数中的选项O_NONBLOCK,选项O_NONBLOCK表示非阻塞,加上这个选项后,表示open调用是非阻塞的,如果没有这个选项,则表示open调用是阻塞的
  3. 对于以只读方式(O_RDONLY)打开的FIFO文件,如果open调用是阻塞的(即第二个参数为O_RDONLY),除非有一个进程以写方式打开同一个FIFO,否则它不会返回;如果open调用是非阻塞的(即第二个参数为O_RDONLY|O_NONBLOCK),则即使没有其他进程以写方式打开同一个FIFO文件,open调用将成功并立即返回。但如果没有其他进程以只读方式打开同一个FIFO文件,open调用将返回-1,并且FIFO也不会被打开
  4. 数据完整性,如果有多个进程写同一个管道,使用O_WRONLY方式打开管道,如果写入的数据长度小于等于PIPE_BUF(4K),那么或者写入全部字节,或者一个字节都不写入,系统就可以确保数据绝不会交错在一起。

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

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

相关文章

YOLOv9图像标注和格式转换

一、软件安装 labelimg安装&#xff08;anaconda&#xff09; 方法一、 pip install labelImg 方法二、 pip install PyQt5 -i https://pypi.tuna.tsinghua.edu.cn/simple/ pip install pyqt5-tools -i https://pypi.tuna.tsinghua.edu.cn/simple/ pip install lxml -i ht…

系统找不到xinput1_3.dll怎么办?试试这五种解决方法轻松搞定

在计算机系统运行过程中&#xff0c;当我们遭遇“找不到xinput1_3.dll”这一错误提示时&#xff0c;实际上正面临一个软件兼容性、系统组件缺失以及游戏或应用程序无法正常启动的关键问题。深入探究这一现象&#xff0c;我们会发现它可能引发一系列连带问题&#xff0c;例如某些…

linux之前后端项目部署与发布

目录 前言 简介 一、安装Nginx 二、后端部署 2.1多个tomcat负载均衡 2.2 负载均衡 2.3 后端项目部署 三、前端部署 1.解压前端 2.Nginx配置文件修改 3.IP域名映射 4.重启Nginx服务 前言 上篇博主已经讲解过了单机项目的部署linux之JAVA环境配置JDK&Tomcat&a…

车载终端_联发科MTK6762车载平板电脑解决方案

智能车载终端方案搭载了MTK联发科8xARM Cortex-A53(64bit)高速CPU&#xff0c;采用12nm工艺制程&#xff0c;提供更快的数据采集速度和APP响应速度&#xff0c;能够快速满足用户的应用需求。配备3GB RAM32GB ROM的低功耗EMCP一体化存储&#xff0c;性能良好&#xff0c;支持多任…

【LeetCode:2476. 二叉搜索树最近节点查询 + 中序遍历 + 有序表】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

python使用winio控制x86工控机的gpio

视频讲解 https://www.bilibili.com/video/BV1Nu4m1w7iv/?vd_source5ba34935b7845cd15c65ef62c64ba82f pywinio库 https://pypi.org/project/pywinio/ 安装库 pip install pywinio寄存器地址 测试代码 import pywinio winio get_winio() # 设置排针2输出1,0x40是bit6置…

嵌入式中逻辑分析仪基本操作方法

前期准备 1.一块能触摸的屏对应的主板机 2.逻辑分析仪对应的软件工具 3.对应的拓展板 4.确定拓展板的引脚分布情况 第一步&#xff1a;逻辑分析仪j基本操作 1.数据捕捉需要先进行对应软件安装,并按照需求进行配置 2.这里以A20为例:此手机使用显示驱动芯片CST148,触摸屏分辨…

插件废土课:打造属于你的“智能笔记”!

哎呀嘞&#xff0c;亲爱的网页冲浪者们&#xff0c;抓紧浮板&#xff0c;我们要继续在Chrome插件的海浪上翻滚啦&#xff01;上次我们玩了个小把戏&#xff0c;搞了个显示时间的Hello World插件&#xff0c;这次我们要把游戏玩大&#xff0c;准备打造一个能让你在网页上乱涂乱画…

数学建模【GM(1, 1)灰色预测】

一、GM(1, 1)灰色预测简介 乍一看&#xff0c;这个名字好奇怪&#xff0c;其实是有含义的 G&#xff1a;Grey&#xff08;灰色&#xff09;M&#xff1a;Model&#xff08;模型&#xff09;(1, 1)&#xff1a;只含有一个变量的一阶微分方程模型 提到灰色&#xff0c;就得先说…

大数据开发项目--音乐排行榜

环境&#xff1a;windows10&#xff0c;centos7.9&#xff0c;hadoop3.2、hbase2.5.3和zookeeper3.8完全分布式&#xff1b; 环境搭建具体操作请参考以下文章&#xff1a; CentOS7 Hadoop3.X完全分布式环境搭建 Hadoop3.x完全分布式环境搭建Zookeeper和Hbase 1. 集成MapReduce…

消息中间件之RocketMQ源码分析(十八)

Broker CommitLog索引机制中的构建过程 1.创建ConsumeQueue和IndexFile。 ConsumeQueue和IndexFile两个索引都是由ReputMessageService类创建的 RequestMessageService类图 ReputMessageService服务启动后的执行过程。 doReput()方法用于创建索引的入口&#xff0c;通常通过…

运用工具Postman快速导出python接口测试脚本

Postman的脚本可以导出多种语言的脚本&#xff0c;方便二次维护开发。 Python的requests库&#xff0c;支持python2和python3&#xff0c;用于发送http/https请求 使用unittest进行接口自动化测试 一、环境准备 1、安装python&#xff08;使用python2或3都可以&#xff09;…

【数据结构与算法】常用算法 前缀和

&#x1f389;&#x1f389;欢迎光临&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;特别推荐给大家我的最新专栏《数据结构与算法&#xff1a;初学者入门指南》&#x1f4d8;&am…

离散数学——树思维导图

离散数学——树思维导图 文章目录 前言内容大纲参考 前言 这是当初学习离散数学时整理的笔记大纲&#xff0c;其中包含了自己对于一些知识点的体悟。现将其放在这里作为备份&#xff0c;也希望能够对你有所帮助。 当初记录这些笔记只是为了在复习时更快地找到对应的知识点。…

Python爬虫之极验滑动验证码的识别

极验滑动验证码的识别 上节我们了解了可以直接利用 tesserocr 来识别简单的图形验证码。近几年出现了一些新型验证码&#xff0c;其中比较有代表性的就是极验验证码&#xff0c;它需要拖动拼合滑块才可以完成验证&#xff0c;相对图形验证码来说识别难度上升了几个等级。本节将…

如何在Linux部署Portainer并结合内网穿透远程管理本地Docker容器

文章目录 前言1. 部署Portainer2. 本地访问Portainer3. Linux 安装cpolar4. 配置Portainer 公网访问地址5. 公网远程访问Portainer6. 固定Portainer公网地址 前言 Portainer 是一个轻量级的容器管理工具&#xff0c;可以通过 Web 界面对 Docker 容器进行管理和监控。它提供了可…

用c# 自己封装的Modbus工具类库源码

前言 Modbus通讯协议在工控行业的应用是很多的&#xff0c;并且也是上位机开发的基本技能之一。相关的类库也很多也很好用。以前只负责用&#xff0c;对其并没有深入学习和了解。前段时间有点空就在这块挖了挖。想做到知其然还要知其所以然。所以就有了自己封装的Modbus工具类库…

Mysql 常用数据类型

数值型(整数)的基本使用 如何定义一个无符号的整数 数值型(bit)的使用 数值型(小数)的基本使用 字符串的基本使用 字符串使用细节 日期类型的基本使用

Orange3数据预处理(列选择组件)数据角色及类型描述

在Orange3的文件组件中&#xff0c;datetime、categorical、numeric以及text代表不同种类的数据类型&#xff0c;具体如下&#xff1a; datetime&#xff1a;代表日期和时间类型的数据。通常用于时间序列分析、生存分析和其他需要考虑时间因素的机器学习任务中。例如&#xff0…

图像读取裁剪与人脸识别

图像读取 Image read ⇒ \Rightarrow ⇒ torchvision.datasets from torchvision import datasets dataset datasets.ImageFolder(data_dir, transformtransforms.Resize((512, 512)))Return value illustration dataset[0][0]是PIL.Image objects&#xff0c;这利用IPyth…