Linux应用开发(8):Linux进程间通信(IPC):管道

Linux应用开发(7):Linux进程间通信(IPC):POSIX消息队列icon-default.png?t=N7T8https://blog.csdn.net/tecsai/article/details/137879465

1. 简述

        我们在前面已经介绍了进程间通信(IPC)常用的“消息队列”。本节将讲解另外一种常用的IPC机制,我们称作管道

        管道可以理解为一种特殊的文件,也可以理解为一种特殊的缓冲区,它允许两个进程通过一个半双工的通道进行数据通信。

2. 基本概念

        上面提到,管道是半双工的,数据只能向一个方向流动。在使用过程中,需要双方同时打开(也可以由父进程先打开,再由子进程继承)。管道分为无名管道和命名管道。

无名管道

        无名管道只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程),它之所以成为无名管道,是因为它们不需要文件系统中的文件支持。管道的缓冲区是有限的。

命名管道

        相对于无名管道,命名管道是基于特殊的文件来进行通信的。在使用时,首先需要文件系统中有一个路径和名称,因此命名管道是可以允许不相关的进程进行通信。

3. 无名管道

        无名管道顾名思义,是没有被命名的管道,其存在于内存中,仅允许相关的两个进程间进行通信。

PS:可以联想到无名信号量和有名信号量,前者在内存中,仅允许关联进程同步,后者则可以在不相关联的进程间进行同步。

        无名管道的创建采用如下API。

#include <unistd.h>

int pipe(int fd[2]);

        fd 是一个整型数组,包含两个元素:fd[0] 用于读取,fd[1] 用于写入。

        无名管道例程。

#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <sys/wait.h>int main(int argc, char* argv[]){int fds[2];pid_t pid;char buffer[50];if (pipe(fds) == -1) {perror("pipe");exit(EXIT_FAILURE);}/** 创建进程. */pid = fork();if (pid == -1) {perror("fork");exit(EXIT_FAILURE);}if (pid == 0) {/** 子进程:写入管道. */close(fds[0]); ///< 关闭读端write(fds[1], "Hello, Parent!", 15);close(fds[1]); ///< 写入后关闭写端} else {/** 父进程:读取管道。 */wait(NULL); ///< 等待子进程结束close(fds[1]); ///< 关闭写端read(fds[0], buffer, 50);close(fds[0]); ///< 读取后关闭读端printf("Parent Process: %s\n", buffer);}return 0;}

4. 命名管道

        命名管道(FIFO)是一种特殊的文件,它允许不相关的进程通过一个命名的路径进行通信。与无名管道不同,命名管道在文件系统中有一个路径和名称。

        创建命名管道的API如下。

#include <sys/stat.h>

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

命名管道例程。

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <fcntl.h>#include <sys/stat.h>int main(int argc, char* argv[]){/** 文件路径. */const char *fifo_name = "my_fifo";int fd;/** 创建命名管道. */if (mkfifo(fifo_name, 0666) == -1) {perror("mkfifo");exit(EXIT_FAILURE);}/** 打开命名管道进行写入. */fd = open(fifo_name, O_WRONLY);if (fd == -1) {perror("open");exit(EXIT_FAILURE);}/** 写入命名管道. */write(fd, "Hello, through FIFO!", 20);close(fd);/** 清理命名管道. */unlink(fifo_name);return 0;}

5. 什么时候选择使用管道

父子进程通信:在C++程序中,你可能需要创建子进程来执行特定的任务。管道可以用来在父进程和子进程之间安全地交换数据。

进程生成和过滤:如果你的应用程序需要生成大量的数据,并且这些数据需要被另一个进程即时处理或过滤,管道可以有效地连接生成器和消费者。

并行处理:在需要并行处理任务时,可以通过管道将任务的输出传递给其他进程,这些进程可以并行地处理数据。

后台任务处理:当你需要在后台运行一个任务,并且不希望阻塞主进程时,可以使用管道来与后台任务通信。

日志记录:管道可以用于实现日志系统,其中一个进程负责记录日志信息,而另一个进程负责监控和处理这些日志。

信号传递:在多进程程序中,管道可以用来传递信号,如通知其他进程某个事件已经发生。

资源共享:当多个进程需要访问同一个资源,但又需要协调访问以避免冲突时,可以使用管道来控制对资源的访问。

简化线程使用:在某些情况下,使用管道进行进程间通信比使用线程更简单,尤其是在涉及复杂同步和锁管理的场景中。

跨平台兼容性:如果你的C++应用程序需要在不同的操作系统上运行,使用管道可以提高代码的可移植性。

模块化设计:在构建模块化的C++应用程序时,管道可以帮助你将不同的功能模块化为独立的进程,并通过管道进行通信。

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

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

相关文章

Latex篇之数学公式

数学公式 背景 科研小白在Latex中踩了不少坑&#xff0c;在此记录一下。 准备资料 以下两份文档可以说贯穿写作始终&#xff0c;务必下载&#xff08;快速过一遍即可&#xff0c;知道怎么用&#xff09; 一份&#xff08;不太&#xff09;简短的 LATEX 2ε 介绍&#xff1…

编写函数fun,它的功能是:根据以下公式求P的值,结果由函数值带回。m与n为两个正整数且要求m>n

本文收录于专栏:算法之翼 https://blog.csdn.net/weixin_52908342/category_10943144.html 订阅后本专栏全部文章可见。 本文含有题目的题干、解题思路、解题思路、解题代码、代码解析。本文分别包含C语言、C++、Java、Python四种语言的解法完整代码和详细的解析。 题干 编写…

Axure如何实现限制选择项数量的交互

大家经常会看到这样的功能设计&#xff1a;可以多选&#xff0c;但是限制多选。比如某招聘网站城市的选择只能选择5个。再选择第6个的时候会提示最多只能选择5项。 这个效果是我们经常会遇到的&#xff0c;在工作中也经常会遇到需要制作这样的效果。今天我们一起来看看&#xf…

光盘完成-qt-动画

QPropertyAnimation 是 Qt 中用于属性动画的类&#xff0c;它允许你动画化任何 QObject 的属性。当你使用 QPropertyAnimation&#xff0c;你应该注意以下几点&#xff1a; 1. **对象和属性的类型**&#xff1a; - QPropertyAnimation 仅支持继承自 QObject 的对象&#xf…

日期类的实现

目录 Date.h Test.cpp 测试代码Test.cpp 日期类的实现 代码分享 Date.h #pragma once #include<iostream> using namespace std; #include<assert.h>class Date {//友元函数声明friend ostream& operator<<(ostream& out, Date& d);friend…

书生·浦语大模型全链路开源体系-第5课

书生浦语大模型全链路开源体系-第5课 书生浦语大模型全链路开源体系-第5课相关资源LMDeploy基础配置LMDeploy运行环境下载internlm2-chat-1_8b模型使用Transformer来直接运行InternLM2-Chat-1.8B模型使用LMDeploy以命令行方式与InternLM2-Chat-1.8B模型对话设置KV Cache最大占用…

2024 Guitar Pro如何加音乐符号及功能介绍

一、新版本特性概览 Guitar Pro v8.1.1 Build 17在保留了前版本强大功能的基础上&#xff0c;进一步优化了用户体验和功能性能。新版本主要更新包括以下几个方面&#xff1a; 界面优化&#xff1a;新版界面更加简洁美观&#xff0c;操作更加便捷&#xff0c;即使是初学者也能快…

mapreduce中的ReduceTask工作机制(Hadoop)

ReduceTask 是 Hadoop 中的一个重要组件&#xff0c;负责对 MapTask 的输出进行合并、排序和归并&#xff0c;最终生成最终的输出结果。 ReduceTask 的工作机制 1. 分组&#xff08;Shuffle&#xff09;阶段&#xff1a; 在分组阶段&#xff0c;ReduceTask 会从多个 Mapper …

【搞钱必看】计算机视觉入门,普通人也能学会的高科技!

目录 1. 计算机视觉&#xff0c;未来科技的金矿 2. 计算机视觉入门&#xff0c;真的那么难吗&#xff1f; 3. 入门步骤&#xff0c;轻松上手 4. 学习资源&#xff0c;助力你的成长 5. 实践是关键&#xff0c;动手操作吧&#xff01; 6. 挑战与机遇并存 啊啊啊啊啊啊啊…

前端开发攻略---Vue项目(Vue2和Vue3)引入高德地图,超详细,超简单,保姆级教程。

1、图片演示 2、引入前的准备 1、前往 高德开放平台 进行账号注册。如果手机上有高德地图App并且已经登录过&#xff0c;则可以直接选择登录 2、注册/登录完成后来到应用管理-->我的应用 3、点击创建新应用 4、填写好应用名称和选择应用类型 5、填写好后点击添加Key 6、填写…

算法新手(一)——位运算、算法是什么、介绍位运算和简单排序

一、二进制、位运算 java中int最大值&#xff0c;2的31次方-1&#xff0c;为什么不是2的32次方-1&#xff1f; ——因为第一位是符号位&#xff0c;0表示正数&#xff0c;1表示复数&#xff1b; 1.1 Integer二进制 -1的二进制&#xff1a; 11111111111111111111111111111111…

2024团体程序设计天梯赛L1-101 别再来这么多猫娘了!

题目链接L1-101 别再来这么多猫娘了&#xff01; #include<iostream> #include<stdio.h> #include<string.h> #include<string> #include<algorithm> using namespace std; string s[105], text; int n, k, ans, a[5005];int main() { // ios::s…