macOS跨进程通信: FIFO(有名管道) 创建实例
一: 简介
在类linux系统中管道分为有名管道和匿名管道。两者都能单方向的跨进程通信。
- 匿名管道(
pipe): 必须是父子进程之间,而且子进程只能由父进程fork() 出来的,才能继承父进程的管道句柄,一般mac 开发用的很少。 - 有名管道(
fifo)又叫命名管道: 可以在同一台机器,没有关系的进程间通信。 其本质是本地创建一个文件,然后使用其路径作为纽带。open后再内核空间产生管道,不同进程之间分别连接管道的读和写的端口进行通信。
这里主要针对有名管道进行研究。
二:主要函数
以下函数在macOS 和 Linux 下均适用。 Windows不行,其创建的关键函数是:CreateNamedPipe(...)
1. int mkfifo(const char *, mode_t);
第一个参数是路径,可以放在tmp路径下,比如const char *fifoName = "/tmp/com.jimbo.fifo";
mode_t代表赋予的权限,测试用0777就可以了。
运行 ls -la /tmp/ 下,明显存在我们创建的管道文件。
有名管道会在 在第一列将会显示类型 s
这里还有其他类型的文件。其中p表示命名管道文件,d表示目录文件,l表示符号连接文件,-表示普通文件,s表示socket文件,c表示字符设备文件,b表示块设备文件。

2. int open(const char *, int, ...)
- 返回值为,打开的管道的操作句柄,读写都需要它
- 第一个参数是路径,同上
- 第二个参数为打开模式:
#define O_RDONLY 0x0000 /* open for reading only */ 只读
#define O_WRONLY 0x0001 /* open for writing only */ 只写
#define O_NONBLOCK 0x00000004 /* no delay */ 不阻塞
...
demo主要使用上面三种模式,
- 发送端使用
O_WRONLY - 接收端使用
O_WRONLY O_NONBLOCK代表open文件的时候,这个方法是否需要阻塞,默认不传是阻塞的.
3. ssize_t read(int, void *, size_t)
往管道读取数据。常规操作,传入open后的返回句柄,和字符串地址和最大长度
4. ssize_t write(int __fd, const void * __buf, size_t __nbyte)
往管道写入数据。常规操作,传入open后的返回句柄,和字符串地址和字符串长度
三:demo代码
如下图,创建了两个app,分别为发送端(写数据)和接收端(读数据)。
macOS App 来说貌似需要双方都是 非沙盒的才行。 不然文件访问不了。

1. 发送端主要逻辑
-
主要创建了
mkfifo一个管道 -
创建了子进程
-
open()阻塞式的等子进程打开管道文件 -
上一步阻塞过了后,点击
writeMsg往管道中写入消息。
主要代码: ViewController.mm 文件代码
//发送端
#import "ViewController.h"
#include <sys/unistd.h>
#include <sys/stat.h>static const char *fifoName = "/tmp/com.jimbo.fifo";@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];[self.view.window setTitle:@"Main window"];int ret = 0;if (access(fifoName, F_OK) == -1) {//管道不存在,创建一个新的ret = mkfifo(fifoName, 0777);if (ret != 0) {NSLog(@"mkfifo failed! ret:%i", ret);return;}}//启动子进程NSString *subAppp = [[NSBundle mainBundle] pathForResource:@"PipeApp_Sub" ofType:@"app"];subAppp = [NSString stringWithFormat:@"%@/Contents/MacOS/PipeApp_Sub", subAppp];NSTask *task = [[NSTask alloc] init];[task setLaunchPath:subAppp];NSError *error;[task launchAndReturnError:&error];//阻塞监听子进程打开 读端。self.writePipeID = open(fifoName,O_WRONLY);printf("open fd:%i\n", self.writePipeID);if(self.writePipeID<0){perror("writer open err");return ;}
}- (IBAction)writeMsg:(id)sender {//往管道发送消息,消息为ui的文本框的数据const char *text = [self.textLabel.stringValue UTF8String];ssize_t writeSize = write(self.writePipeID, text, strlen(text)+1);NSLog(@"write succed size:%zi", writeSize);
}
2. 接收端主要逻辑
-
收到非阻塞的
O_NONBLOCK打开只读管道,(打开后发送端的阻塞会通过) -
等到发送端发送了数据后。。。
-
点击接收数据的按钮
receiveMsg,read()函数读取管道中的数据,并显示在ui的textView中
//接收端
#import "ViewController.h"
#include <sys/stat.h>@interface ViewController()
@property (nonatomic, assign) int pipeReadID;
@property (unsafe_unretained) IBOutlet NSTextView *textView;@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];const char *fifoName = "/tmp/com.jimbo.fifo";// 由于是ui 主线程,所以选择了 非阻塞式的打开 管道self.pipeReadID = open(fifoName, O_RDONLY | O_NONBLOCK);if (self.pipeReadID < 0) {NSLog(@"open 失败了");self.textView.string = @"open 失败了";} else {self.textView.string = @"点击接收按钮,接收数据";}
}- (IBAction)receiveMsg:(id)sender {size_t n;char line[PIPE_BUF+1];n = read(self.pipeReadID, line, PIPE_BUF);NSLog(@"count:%zu get msg: %s", n ,line);if (n > PIPE_BUF || n < 0) {return;}self.textView.string = [NSString stringWithFormat:@"收到的数据:%@", [[NSString alloc] initWithBytes:line length:n encoding:NSUTF8StringEncoding]];
}- (void)dealloc {close(self.pipeReadID);
}@end
相关文章:
macOS跨进程通信: FIFO(有名管道) 创建实例
一: 简介 在类linux系统中管道分为有名管道和匿名管道。两者都能单方向的跨进程通信。 匿名管道(pipe): 必须是父子进程之间,而且子进程只能由父进程fork() 出来的,才能继承父进程的管道句柄,一般mac 开发…...
推荐几个免费的HTTP接口Mock网站和工具
在前后端分离开发架构下,经常遇到调用后端数据API接口进行测试、集成、联调等需求,比如: (1)前端开发人员很快开发完成了UI界面,但后端开发人员的API接口还没有完成,不能进行前后端数据接口对接…...
企业数据库安全管理规范
1.目的 为规范数据库系统安全使用活动,降低因使用不当而带来的安全风险,保障数据库系统及相关应用系统的安全,特制定本数据库安全管理规范。 2.适用范围 本规范中所定义的数据管理内容,特指存放在信息系统数据库中的数据。 本…...
react:ffcreator中FFCreatorCenter视频队例
最近项目要求,一键生成房子的推荐视频,选几张图,加上联系人的方式就是一个简单的视频,因为有web端、小程序端,为了多端口用,决定放在服务器端生成。 目前用的是react中的nextjs来开发项目。 nextjs中怎样…...
力扣(leetcode)第434题字符串中的单词数(Python)
434.字符串中的单词数 题目链接:434.字符串中的单词数 统计字符串中的单词个数,这里的单词指的是连续的不是空格的字符。 请注意,你可以假定字符串里不包括任何不可打印的字符。 示例: 输入: “Hello, my name is John” 输出: 5 解释: 这…...
django学习:页面渲染与请求和响应
1.请求过程 2.页面渲染 在app中新建一个目录(Directory),文件名命名为templates。该文件名命名是固定的,不可命名出错,如若后续步骤出错,该目录文件名是一个检查的重点项目。在该目录下新建一个html文件&a…...
Redis 数据一致性
概述 当我们在使用缓存时,如果发生数据变更,那么你需要同时操作缓存和数据库,而它们两个又分属不同的系统,因此无法做到同时操作成功或失败,因此在并发读写下很可能出现缓存与数据库数据不一致的情况 理论上可以通过…...
Mac环境下反编译apk
Mac环境下反编译apk 安装反编译工具dex2jar:[官网下载](https://sourceforge.net/projects/dex2jar/)JD-GUI:[官网下载](https://jd-gui.apponic.com/) 实操1. 将需要反编译的 .apk 文件放在下载的 dex2jar 文件夹目录下2. 使用 cd /xxx/dex2jar-2.0 命令…...
计算机网络——网络模型的组织、看法以及标准化流程
1. 通信技术和标准化领域中扮演重要角色的组织 1.1 国际和国家官方标准化机构 OSI:国际标准化组织(ISO),负责国际标准的制定,旨在确保全球产品和服务的安全性、可靠性和效率。它有许多国家分支机构,包括法…...
【JAVA】volatile 关键字的作用
🍎个人博客:个人主页 🏆个人专栏: JAVA ⛳️ 功不唐捐,玉汝于成 目录 前言 正文 volatile 的作用: 结语 我的其他博客 前言 在多线程编程中,保障数据的一致性和线程之间的可见性是…...
Next.js 第一次接触
因为需要整个漂亮的在线文档,所以接触了next.js,因为对前端js本身不够熟悉,别说对react.js 又不会,时间又不允许深入研究,所以,为了加一个导航菜单,极其痛苦。 有点小bug,不过不影响…...
CISSP 第7章:PKI和密码学应用
第七章 PKI和密码学应用 7.1 非对称密码学 对称密码系统具有共享的秘钥系统,从而产生了安全秘钥分发的问题 非对称密码学使用公钥和私钥对,无需支出复杂密码分发系统 7.1.1 公钥与私钥 7.1.2 RSA(兼具加密和数字签名) RSA算法依赖…...
dji uav建图导航系列()ROS中创建dji_sdk节点包(二)实现代码
在前文 【dji uav建图导航系列()ROS中创建dji_sdk节点包(一)项目结构】中简单介绍了项目的结构,和一些配置文件的代码。本文详细说明目录src下的节点源代码实现。 文章目录 1、代码结构2、PSDK部分3、ROS部分3.1、头文件3.1.1、外部调用 node_service.h3.1.2、节点类定义…...
数字化工厂产品推荐 带OPC UA的分布式IO模块
背景 近年来,为了提升在全球范围内的竞争力,制造企业希望自己工厂的机器之间协同性更强,自动化设备采集到的数据能够发挥更大的价值,越来越多的传统型工业制造企业开始加入数字化工厂建设的行列,实现智能制造。 数字化…...
使用OHOS SDK构建opus
参照OHOS IDE和SDK的安装方法配置好开发环境。 从github下载源码。 执行如下命令: git clone --depth1 https://github.com/xiph/opus进入源码所在的目录,创建批处理文件ohos_build.cmd,内容如下: echo off setlocalset OHOS_…...
K-means 聚类算法分析
算法简述 K-means 算法原理 我们假定给定数据样本 X ,包含了 n 个对象 ,其中每一个对象都具有 m 个维度的属性。而 K-means 算法的目标就是将 n 个对象依据对象间的相似性聚集到指定的 k 个类簇中,每个对象属于且仅属于一个其到类簇中心距离…...
uniapp获取定位
Uniapp 是一种跨平台应用开发框架,它能够快速地构建出针对不同平台的应用程序。在Uniapp中,实现定位功能也变得十分简单,只需要简单的配置就能轻松实现。 一、高德地图根据指定位置获取经纬度 参考地址:地理/逆地理编码-基础 API…...
Python 面向对象之反射
Python 面向对象之反射 【一】概念 反射是指通过对象的属性名或者方法名来获取对象的属性或调用方法的能力反射还指的是在程序额运行过程中可以动态获取对象的信息(属性和方法) 【二】四个内置函数 又叫做反射函数 万物皆对象(整数、字符串、函数、模块、类等等…...
HPM6750开发笔记《DMA接收和发送数据UART例程深度解析》
目录 概述: 端口设置: 代码分析: 运行现象: 概述: DMA(Direct Memory Access)是一种计算机系统中的数据传输技术,它允许数据在不经过中央处理器(CPU)的直…...
SQL IN 操作符
IN 操作符 IN 操作符允许您在 WHERE 子句中规定多个值。 SQL IN 语法 SELECT column1, column2, ... FROM table_name WHERE column IN (value1, value2, ...); 参数说明: column1, column2, ...:要选择的字段名称,可以为多个字段。如果…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
C/C++ 中附加包含目录、附加库目录与附加依赖项详解
在 C/C 编程的编译和链接过程中,附加包含目录、附加库目录和附加依赖项是三个至关重要的设置,它们相互配合,确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中,这些概念容易让人混淆,但深入理解它们的作用和联…...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...
第7篇:中间件全链路监控与 SQL 性能分析实践
7.1 章节导读 在构建数据库中间件的过程中,可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中,必须做到: 🔍 追踪每一条 SQL 的生命周期(从入口到数据库执行)&#…...
手机平板能效生态设计指令EU 2023/1670标准解读
手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读,综合法规核心要求、最新修正及企业合规要点: 一、法规背景与目标 生效与强制时间 发布于2023年8月31日(OJ公报&…...
C++ 类基础:封装、继承、多态与多线程模板实现
前言 C 是一门强大的面向对象编程语言,而类(Class)作为其核心特性之一,是理解和使用 C 的关键。本文将深入探讨 C 类的基本特性,包括封装、继承和多态,同时讨论类中的权限控制,并展示如何使用类…...
CVE-2023-25194源码分析与漏洞复现(Kafka JNDI注入)
漏洞概述 漏洞名称:Apache Kafka Connect JNDI注入导致的远程代码执行漏洞 CVE编号:CVE-2023-25194 CVSS评分:8.8 影响版本:Apache Kafka 2.3.0 - 3.3.2 修复版本:≥ 3.4.0 漏洞类型:反序列化导致的远程代…...
C++ Saucer 编写Windows桌面应用
文章目录 一、背景二、Saucer 简介核心特性典型应用场景 三、生成自己的项目四、以Win32项目方式构建Win32项目禁用最大化按钮 五、总结 一、背景 使用Saucer框架,开发Windows桌面应用,把一个html页面作为GUI设计放到Saucer里,隐藏掉运行时弹…...
