linux进程间通信-FIFO,让你全方位理解

news2024/9/21 0:31:27

有名管道(FIFO)

有名管道也被称为FIFO文件,是一种特殊的文件。由于linux所有的事物都可以被视为文件,所以对有名管道的使用也就变得与文件操作非常统一。

(1)创建有名管道

用如下两个函数中的其中一个,可以创建有名管道。

#include

#include

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

filname是指文件名,而mode是指定文件的读写权限。

(2)打开有名管道

和打开其他文件一样,可以用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就是传递给open调用的是FIFO的路径名,而不是正常的文件。(如:

const char *fifo_name = "/tmp/my_fifo";)

3第二个参数中的选项O_NONBLOCK,选项O_NONBLOCK表示非阻塞,加上这个选项后,表示open调用是非阻塞的,如果没有这个选项,则表示open调用是阻塞的。

(3)阻塞问题

对于以只读方式(O_RDONLY)打开的FIFO文件,如果open调用是阻塞的(即第二个参数为O_RDONLY),除非有一个进程以写方式打开同一个FIFO,否则它不会返回;如果open调用是非阻塞的的(即第二个参数为O_RDONLY | O_NONBLOCK),则即使没有其他进程以写方式打开同一个FIFO文件,open调用将成功并立即返回。

对于以只写方式(O_WRONLY)打开的FIFO文件,如果open调用是阻塞的(即第二个参数为O_WRONLY),open调用将被阻塞,直到有一个进程以只读方式打开同一个FIFO文件为止;如果open调用是非阻塞的(即第二个参数为O_WRONLY | O_NONBLOCK),open总会立即返回,但如果没有其他进程以只读方式打开同一个FIFO文件,open调用将返回-1,并且FIFO也不会被打开。

(4)使用FIFO实现进程间的通信

管道的写入端从一个文件读出数据,然后写入写管道。管道的读取端从管道读出后写到文件中。

写入端代码:fifowrite.c

#include

#include

#include

#include

#include

#include

#include

#include

int main()

{

const char *fifo_name = "/tmp/my_fifo";

int pipe_fd = -1;

int data_fd = -1;

int res = 0;

const int open_mode = O_WRONLY;

int bytes_sent = 0;

char buffer[PIPE_BUF + 1];

int bytes_read = 0;

if(access(fifo_name, F_OK) == -1)

{

printf ("Create the fifo pipe.\n");

res = mkfifo(fifo_name, 0777);

if(res != 0)

{

fprintf(stderr, "Could not create fifo %s\n", fifo_name);

exit(EXIT_FAILURE);

}

}

printf("Process %d opening FIFO O_WRONLY\n", getpid());

pipe_fd = open(fifo_name, open_mode);

printf("Process %d result %d\n", getpid(), pipe_fd);

if(pipe_fd != -1)

{

bytes_read = 0;

data_fd = open("Data.txt", O_RDONLY);

if (data_fd == -1)

{

close(pipe_fd);

fprintf (stderr, "Open file[Data.txt] failed\n");

return -1;

}

bytes_read = read(data_fd, buffer, PIPE_BUF);

buffer[bytes_read] = '\0';

while(bytes_read > 0)

{

res = write(pipe_fd, buffer, bytes_read);

if(res == -1)

{

fprintf(stderr, "Write error on pipe\n");

exit(EXIT_FAILURE);

}

bytes_sent += res;

bytes_read = read(data_fd, buffer, PIPE_BUF);

buffer[bytes_read] = '\0';

}

close(pipe_fd);

close(data_fd);

}

else

exit(EXIT_FAILURE);

printf("Process %d finished\n", getpid());

exit(EXIT_SUCCESS);

}

管道读取端: fiforead.c

#include

#include

#include

#include

#include

#include

#include

#include

int main()

{

const char *fifo_name = "/tmp/my_fifo";

int pipe_fd = -1;

int data_fd = -1;

int res = 0;

int open_mode = O_RDONLY;

char buffer[PIPE_BUF + 1];

int bytes_read = 0;

int bytes_write = 0;

memset(buffer, '\0', sizeof(buffer));

printf("Process %d opening FIFO O_RDONLY\n", getpid());

pipe_fd = open(fifo_name, open_mode);

data_fd = open("DataFormFIFO.txt", O_WRONLY|O_CREAT, 0644);

if (data_fd == -1)

{

fprintf(stderr, "Open file[DataFormFIFO.txt] failed\n");

close(pipe_fd);

return -1;

}

printf("Process %d result %d\n",getpid(), pipe_fd);

if(pipe_fd != -1)

{

do

{

res = read(pipe_fd, buffer, PIPE_BUF);

bytes_write = write(data_fd, buffer, res);

bytes_read += res;

}while(res > 0);

close(pipe_fd);

close(data_fd);

}

else

exit(EXIT_FAILURE);

printf("Process %d finished, %d bytes read\n", getpid(), bytes_read);

exit(EXIT_SUCCESS);

}

(5)有名管道的安全问题

有一种情况是:一个FIFO文件,有多个进程同时向同一个FIFO文件写数据,而只有一个读FIFO进程在同一个FIFO文件中读取数据时,会发生数据块的相互交错。不同进程向一个FIFO读进程发送数据是很普通的情况。这个问题的解决方法,就是让写操作的原子化。系统规定:在一个以O_WRONLY(即阻塞方式)打开的FIFO中, 如果写入的数据长度小于等待PIPE_BUF,那么或者写入全部字节,或者一个字节都不写入。如果所有的写请求都是发往一个阻塞的FIFO的,并且每个写记请求的数据长度小于等于PIPE_BUF字节,系统就可以确保数据决不会交错在一起。

嵌入式物联网需要学的东西真的非常多,千万不要学错了路线和内容,导致工资要不上去!

无偿分享大家一个资料包,差不多150多G。里面学习内容、面经、项目都比较新也比较全!某鱼上买估计至少要好几十。(点击找小助理领取)

 

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

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

相关文章

python项目上线

python项目上线一 购买服务器二 使用MobaXterm连接服务器三 上线图四 安装git五 安装mysql六 安装redis七 安装python八 安装uwsgi九 安装虚拟环境十 安装nginx十一 前端部署十二 后端部署12.1 git拉取代码,安装依赖12.2 配置数据库12.3 迁移数据库12.4 使用uwsgi启…

作为微软开发者官方号,我们又要做点特别的事情了

在“感谢”二字最容易说出口的日子 谢谢每一个你,像一颗颗星星一样 点亮 MSDN 微软开发者社区的技术宇宙 我们也将在这个最值得感谢的日子 做一点特别的事情 MSDN 到底什么来头? MSDN 微软开发者社区已经成立快10年了,相信有很多资深开发…

Android服务器的通信方式

目录 一.HTTP协议 1.简介 2.Get和Post的使用 1.Get请求 2.Post请求 3.Get请求和Post请求的区别 二.Socket Socket的使用类型主要有两种: 客户端: 三.Socket 与 Http 对比 Android与服务器的通信方式主要有两种,一是Http通信&#xf…

Docker安装Gitlab-ruuner

第一步 # 拉取镜像 docker pull gitlab/gitlab-runner:latest # 启动容器 docker run -d --name gitlab-runner --restart always -v /opt/gitlab-runner/config:/etc/gitlab-runner -v /var/run/docker.sock:/var/run/docker.sock gitlab/gitlab-runner:latest 第二步 查看/…

Windows 上修改 docker 的镜像文件存储位置(修改 WSL 文件映射)

Windows 上修改 docker 的镜像文件存储位置(修改 WSL 文件映射)1、起因2、修改2.1 关闭 Docker Desktop2.2 备份镜像2.3 WSL 取消注册 docker-desktop-data2.4 镜像数据导回 WSL 并挂载到新路径3、验证1、起因 一开始在 Windows 上安装了 docker 后&…

运动用品品牌排行榜,2022年值得买的运动用品推荐

如今,人们的生活节奏越来越快,工作和生活压力大。因此,人们越来越重视体育运动,通过体育运动达到放松和锻炼身体的目的,运动装备也就跟着火热起来。无论是进行室内或户外活动,选一套合适的运动装备是很有必…

【java】java 类型安全 与 unchecked warning

1.概述 1.1. What does type-safety mean? 我的总结: 从概念上来说,Type Safety,最本质上,就是对于内存(Memory)的“正确访问”。假如说,在内存的一块区域上存储着一个String类型的对象;按照正常的逻辑,这块内存区域就应该被当作String来进行处理,这就是所谓的“…

MASA Framework 事件总线 - 进程内事件总线

概述 事件总线是一种事件发布/订阅结构,通过发布订阅模式可以解耦不同架构层级,同样它也可以来解决业务之间的耦合,它有以下优点 松耦合横切关注点可测试性事件驱动 发布订阅模式 通过下图我们可以快速了解发布订阅模式的本质 订阅者将自…

nginx简单学习笔记

目录什么是nginx?反向代理负载均衡动静分离安装nginxNginx常用命令nginx.conf配置文件1、位置2 nginx配置文件组成Nginx 反向代理实例Nginx 配置实例-负载均衡nginx 分配服务器策略Nginx配置实例-动静分离nginx原理什么是nginx? Nginx是一个高性能的 HT…

【附源码】计算机毕业设计JAVA医院住院综合服务管理系统

【附源码】计算机毕业设计JAVA医院住院综合服务管理系统 目运行 环境项配置: Jdk1.8 Tomcat8.5 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: …

第五站:操作符(第一幕)

操作符相关的知识,在我们初识C语言(第三幕)这篇文章中其实已经讲到过了。但是那一次讲解仅仅只是一些粗略的知识讲解,我们在那里面已经提到过,后续会专门超级详细的讲解操作符的知识,我们现在就来攻下操作符…

2022亚太数学杯数学建模竞赛B题(思路、程序......)

🍒🍒🍒欢迎关注🌈🌈🌈 📝个人主页:我爱Matlab 👍点赞➕评论➕收藏 养成习惯(一键三连)🌻🌻🌻 🍌希…

C妈妈加密返回值逆向分析

内容仅供参考学习 目标 网址:https://www.chanmama.com/promotionDetail/0IHXaJ1y7lRNaZyiTsKa6vHtvaZDe6zy/live 直播记录接口返回值加密 分析 打开调试工具,先截获一个请求: 进入Initiator 一般情况通过这边进入函数中挨着…

HTML CSS游戏官网网页模板 大学生游戏介绍网站毕业设计 DW游戏主题网页模板下载 游戏娱乐网页成品代码

🎉精彩专栏推荐👇🏻👇🏻👇🏻 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业…

#边学边记 必修5 高项:对人管理 第2章 项目沟通管理和干系人管理 2-5 项目干系人管理

导学 重要知识点:干系人分析,干系人分类、分析技术、项目干系人管理过程的输入、工具与技术、输出等。下午的案例题可能会涉及与项目干系人管理知识点相关的简答题。 干系人管理的过程 1. 识别干系人 识别能够影响项目决策、活动或结果的个人、群体或…

Lysozyme C (46-61) (chicken),62982-31-4

AMPs是由相对较小的分子组成的异质基团,通常含有不到100个氨基酸。 它们最初是在20世纪60年代由Zeya和Spitznagel 在多形核白细胞溶酶体中描述的。 迄今为止,已在数据库(如数据库)中 确定和登记了2600多个AMP。 它们是由几乎所有的…

Mysql语法三:表的约束和表与表之间的关系以及高级查询

目录 1.表的约束 1.1:约束类型 1.2:NULL约束 1.3:UNIQUE:唯一约束 1.4:DEFAULT :默认值约束 1.5:PRIMARY KEY:主键约束 1.5.1:联合主键 1.5.2:自增主键 1.6:FORE…

HOOPS 3DGS技术概述

1.什么是HOOPS 3D图像系统 HOOPS 3D图形系统(HOOPS/3DGS)是一款高性能3D图形工具包,适用于开发人员构建Windows和UNIX操作系统以及Internet应用程序。HOOPS/3DGS高度优化的数据结构和算法大大简化了基于CAD/CAM/CAE、科学可视化和地理信息系…

Flutter的三棵树

一、Flutter常见的家族成员 Widget常见的家族成员 Element常见的家族成员 Render常见的家族成员 二、示例代码对应的Flutter Inspector树 示例代码:MyApp->MyHomePage->ErrorWidget,包含了StatelessWidget、StatefulWidget、LeafRenderObjectWid…

远程医疗解决方案-最新全套文件

远程医疗解决方案-最新全套文件一、建设背景二、建设思路三、建设方案四、获取 - 远程医疗全套最新解决方案合集一、建设背景 针对当今社会医疗资源分布不均、看病难看病贵、医学单位间学术交流和研讨开展困难,华为公司推出了远程医疗解决方案,实现远程…