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

news2024/11/12 20:35:19

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.coloradmin.cn/o/1612103.html

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

相关文章

[大模型]TransNormerLLM-7B FastApi 部署调用

TransNormerLLM-7B FastApi 部署调用 1. TransNormer 介绍 TransNormerLLM 是一个基于线性注意力的 LLM&#xff0c;在准确性和效率方面均优于传统的基于 softmax 注意力的模型。它是在包含多达1.4 万亿个令牌的高质量语料库上进行训练的&#xff0c;TransNormerLLM 从之前的…

【Scientific American】【科学美国人杂志】2024年4月号:目录部分

说明&#xff1a; 仅供学习、参考使用&#xff0c;请勿用于商业用途。 本期购于新加坡&#xff0c;封面图&#xff1a; Contents Special Report: What we’re learning from AI The Race to Decode an Ancient Scroll How scientists, students, gamers and Silicon Valle…

在 Linux 中删除文件和文件夹

目录 ⛳️推荐 前言 删除文件 &#x1f3cb;️练习文件删除 小心删除 删除目录 &#x1f3cb;️练习文件夹删除 测试你的知识 ⛳️推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到…

setmapAVL树红黑树

目录 关联式容器树形结构的关联式容器setset的模板参数列表set的构造函数set的迭代器set的容量操作set其他操作 multisetmap键值对map的模板参数列表map的迭代器map中元素的修改map的容量与元素访问 multimap底层结构avl树avl树概念AVL树结点的定义AVL树的插入AVL树的旋转AVL树…

(助力国赛)美赛O奖数学建模可视化!!!含代码3(误差限图、冰柱图、树图)

众所周知&#xff0c;数学建模的过程中&#xff0c;将复杂的数据和模型结果通过可视化图形呈现出来&#xff0c;不仅能够帮助我们更深入地理解问题&#xff0c;还能够有效地向评委展示我们的研究成果。   今天&#xff0c;承接《可视化代码2》&#xff0c;作者将与大家分享《…

我用ADAU1467加5个ADAU1772,做20进10出的音频处理板(一):硬件设计思路和原理图

作者的话 ADAU1467是现阶段ADI支持最多通道的ADAU音频DSP&#xff0c;他配合外部的AD/DA&#xff0c;可以实现最多32路音频通道&#xff0c;接了一个小项目&#xff0c;我拿它做了一块20进10出的板&#xff0c;10个MIC/LINE输入,10个LINE IN输入&#xff0c;10个HPOUT&#xf…

Redis(二) 单线程架构

redis 的单线程架构 我们都知道 redis 作为缓存&#xff0c;读取速度是非常快的&#xff0c;但是大家知道 redis 的线程架构是怎样的呢&#xff1f;也就是说&#xff0c;redis 是多线程架构还是单线程架构呢&#xff1f; 我们通过一个例子来了解&#xff1a; 首先在 redis 服…

基于Web的宠物医院信息管理系统论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本宠物医院信息管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据…

【C++】explicit关键字详解(explicit关键字是什么? 为什么需要explicit关键字? 如何使用explicit 关键字)

目录 一、前言 二、explicit关键字是什么&#xff1f; 三、构造函数还具有类型转换的作用 &#x1f34e;单参构造函数 ✨引出 explicit 关键字 &#x1f34d;多参构造函数 ✨为什么需要explicit关键字&#xff1f; ✨怎么使用explicit关键字&#xff1f; 四、总结 五…

MariaDB InnoDB 空洞清理

1、背景 数据库占用服务器内存越来越高&#xff0c;除了bin-log文件之外&#xff0c;还发现了一些带有text或者longtext数据类型字段的表&#xff0c;这种表也会占用很高的服务器磁盘空间 数据库版本&#xff1a; 表引擎&#xff1a; InnoDB 数据量&#xff1a;清理之前1500万…

python安装的详细步骤

下载 1.打开Python官网.我们建议工具类的测试软件还是官网下载比较靠谱. https://www.python.org/getit/ 2.在下图界面中选择需要的方式进行点击 3.直接点击下载.可以进入保存界面,进行保存即可下载,后续安装 4.鼠标放在Downloads显示平台和版本选择界面,点击Windows,进入wi…

【备战算法岗】—— 控制模块复习(持续更新!!!)

1 控制理论基础 1.1 控制模块概述 输入&#xff1a;轨迹线Reference、地图信息、定位信息、车辆反馈信息 输出&#xff1a;刹车、油门、转向 CANBUS&#xff1a;车辆底盘交互协议 参考博客&#xff1a;Apollo CANBUS模块解析 apollo&#xff1a;canbus模块&#xff08;1&…

【超萌二次元动漫个人主页HTML源码】

效果图 部分代码 index.htnl <!DOCTYPE HTML> <html> <head> <title>个人主页介绍页</title> <meta name"keywords" content"孤客个人主页介绍页"> <meta name"description" content"孤客个…

曲线救国|基于函数计算FC3.0部署AI数字绘画stable-diffusion

曲线救国|基于函数计算FC3.0部署AI数字绘画stable-diffusion 基于函数计算FC2.0部署AI数字绘画stable-diffusion基于函数计算FC3.0部署AI数字绘画stable-diffusion总结 在经过了上一次曲线救国失败经历之后&#xff0c;失败经历参考博文&#xff1a;https://developer.aliyun.c…

PF滤波?

粒子滤波 本文是对于原文的学习与部分的转载 https://blog.csdn.net/weixin_44044161/article/details/125445579 粒子滤波是在目标跟踪中常用的一种方法 非线性条件下&#xff0c;贝叶斯滤波面临一个重要的问题是状态分布的表达与积分式的求解 由前面章节中的分析可以得知…

Jupyter的下载与安装

1.下载&#xff1a; 在anaconda的指定环境中 conda install nb_conda_kernels 2.打开 在anaconda指定环境中使用命令&#xff1a; jupyter notebook 3.输入指令后&#xff0c;会显示如下&#xff0c;根据显示地址打开 3. 在右边的new按钮处&#xff0c;选择相应环境&…

C++参考手册使用说明

C参考手册使用说明 文章目录 C参考手册使用说明1 为什么要使用C参考手册2 网站3 C参考手册离线格式4 C参考手册使用说明1.1 离线C参考手册下载1.2 html离线C参考手册1.3 chm离线C参考手册1.4 linux安装包C参考手册&#xff08;只有英文版本&#xff09;1.5 qch离线C参考手册 更…

oracle操作系统OS认证和密码文件认证

1 说明 1.1 常见认证方式 Oracle登录认证方式主要涉及到如何验证用户身份以访问数据库。Oracle数据库提供了多种认证机制来确保数据的安全性和访问控制&#xff0c;每种方式都有其特定的使用场景和安全性考虑。以下是Oracle中常见的登录认证方式&#xff1a; 1、基于操作系统…

【从浅学到熟知Linux】基础IO第一弹=>C语言文件操作接口、文件系统调用、文件描述符概念及分配规则

&#x1f3e0;关于专栏&#xff1a;Linux的浅学到熟知专栏用于记录Linux系统编程、网络编程等内容。 &#x1f3af;每天努力一点点&#xff0c;技术变化看得见 文章目录 C语言文件接口回顾系统文件概念与接口文件基本概念系统接口openreadwritecloselseek 什么是当前路径 文件描…

CTFHUB RCE作业

题目地址&#xff1a;CTFHub 完成情况如图&#xff1a; 知识点&#xff1a; preg_match_all 函数 正则匹配函数 int preg_match_all ( string $pattern , string $subject [, array &$matches [, int $flags PREG_PATTERN_ORDER [, int $offset 0 ]]] )搜索 subject 中…