进程间通信 管道

news2025/6/9 17:49:45

在Linux中,管道是一种通信机制,用于将一个程序的输出直接连接到另一个程序的输入。从本质上说,管道也是一种文件,但它又和一般的文件有所不同,它可以克服使用文件进行通信的两个问题,具体表现为限制管道的大小和读取进程可能工作得比写进程快。管道的思想是在内存中创建一个共享文件,从而使通信双方利用这个共享文件来传递信息。由于这种方式具有单向传递数据的特点,所以这个作为传递消息的共享文件就叫做“管道”。在管道的具体实现中,根据通信所使用的的文件是否具有名称,有“匿名管道”和“命名管道”。

匿名管道是一种具有亲缘关系的进程间的通信机制,它由创建它的进程及其子孙进程使用。匿名管道由pipe函数创建并打开。

命名管道克服了匿名管道只能在具有亲缘关系进程间通信的缺点,使不具有亲缘关系的进程间也能通过命名管道进行通信。命名管道由mkfifo函数创建。命名管道在文件系统中有对应的文件名。命名管道通过打开该文件名来打开管道,从而实现与其他进程的通信。

管道是连接两个进程的连接器(特殊文件)

匿名管道

当一个管道建立后,将获得两个文件描述符,分别用于对管道读取写入,通常将其称为管道的读端写端

image-20231202182312664

image-20231202182327485

所用到的函数:

#include <unistd.h>
int pipe(int pipefd[2]);

参数说明:

pip数组:存放两个文件描述符

  • pipefd[0]:存放管道读端文件描述符。
  • pipefd[1]:存放管道写端文件描述符。

返回值:

  • 调用成功,返回0
  • 调用失败,返回-

管道的读写操作

读规则
  1. 关闭管道的写端
close(fd[1]);
  1. 从管道读端fd[0]读出size个字符放到buf
read(fd[0], buf, size);
  1. 读完关闭管道的读端
close(fd[0]);
写规则
  1. 关闭管道的读端
close(fd[0]);
  1. buf中的长度为size的字符送到写端fd[1]
write(fd[1], buf, size);
  1. 写完关闭管道的写端
close(fd[1]);

例子:在父进程向管道内写入"Hello World\n",之后在子进程中读取内容。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int main()
{
    int fd[2];
    int ret = pipe(fd);
    char buf[100] = "Hello Wrold\n";
    if(ret == -1) {
        perror("pipe error");
        exit(1);
    }
    pid_t pd = fork();
    if(pd > 0) {
        // 关闭读端
        close(fd[0]);
        // 用写端,写入内容
        write(fd[1], buf, sizeof(buf));
        close(fd[1]);
        wait(NULL);
    } else if(pd == 0) {
        // 关闭写端
        close(fd[1]);
        // 从读端读取内容
        read(fd[0], buf, sizeof(buf));
        close(fd[0]);
        write(STDOUT_FILENO, buf, sizeof(buf));
        close(fd[0]);
    }
}

命名管道

命名管道与匿名管道的区别:

  • 匿名管道位于内存,只能用于有亲缘关系的进程通信
  • 命名管道位于文件系统中,可以实现不同进程之间的通信
  • 命名管道是一种双向通信管道,可以移动读/写模式打开

所用到的函数:

#include <sys/types.h>
#include <unistd.h>
int mkfifo(const char* pathname, mode_t mode);

参数说明:

  • pathname:创建的FIFO文件名
  • mode:规定FIFO文件的读写权限

返回值:

  • 成功时,返回0
  • 失败时,返回-1

创建一个叫np的命名管道

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int main()
{
    if(mkfifo("np", 0644) < 0) {
        perror("Error!");
        exit(1);
    }
    return 0;
}

向管道写入内容:

#include <stdio.h>  
#include <stdlib.h>  
#include <fcntl.h>  
#include <unistd.h>  
  
int main() {  
    pid_t fd;  
    // 指定文件的完整路径,如果文件不存在,将会创建  
    if ((fd = open("np", O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR)) < 0) {  
        perror("error");  
        exit(-1);  
    }  
    printf("%d\n", fd);  
    char buf[]  = "Hello World\n";  
    write(fd, buf, sizeof(buf));  
    close(fd);  
    printf("write success\n");  
    return 0;  
}

读出内容:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
int main()
{
    pid_t fd;
    char buf[100];
    if( (fd = open("np", O_RDONLY)) < 0) {
        perror("Error\n");
        exit(-1);
    }
    while( (read(fd, buf, sizeof(buf))) > 0) {
        write(STDOUT_FILENO, buf, sizeof(buf));
    }
    return 0;
}

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

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

相关文章

基于SSM的生鲜在线销售系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

[传智杯 #2 决赛] 补刀

题目描述 UIM 在写程序的空闲玩一款 MOBA 游戏。 当敌方的小兵进入到我方防御塔的范围内&#xff0c;就会持续受到防御塔造成的伤害&#xff1b;当然我方英雄也可以对它造成伤害。当小兵的血量降到了 0 或者更低&#xff0c;就会被击杀。为了获得经验&#xff0c;UIM 希望在防…

Vmware 中的Centos7.9 和 主机共享文件夹

1.开启虚拟机的共享文件夹功能。 虚拟机->设置->选项-共享文件夹&#xff1a;【总是启用】 2.添加一个共享文件夹 3. 虚拟机中创建一个文件夹 mkdir share cd share pwd /www/backup/share4.挂载共享文件夹 /usr/bin/vmhgfs-fuse .host:/share /www/backup/share -o s…

Java 设计模式系列:代理模式

文章目录 介绍静态代理基本介绍应用实例静态代理优缺点 动态代理基本介绍JDK 中生成代理对象的 API Cglib 代理基本介绍实现步骤 介绍 1&#xff09;代理模式&#xff1a;为一个对象提供一个替身&#xff0c;以控制对这个对象的访问。即通过代理对象访问目标对象 2&#xff09…

深入理解原码、反码、补码(结合C语言)

一、引出问题 在学习C语言单目操作符中~按位取反的过程中&#xff0c;对这样一段代码的结果产生了疑惑&#xff1a; #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h>int main() {int a 0;int b ~a;//按位取反printf("%d\n", b);return 0; }输出结果…

系列十七、理解SpringBoot中的starter 自定义一个starter

一、概述 作为后端Java程序员&#xff0c;基本上公司的日常开发都是基于SpringBoot进行的&#xff0c;我们使用SpringBoot也是沉醉于它的各种各样的starter带给我们的便利&#xff0c;这些starter为我们带来了众多的自动化配置&#xff0c;通过这些自动化配置&#xff0c;我们可…

为自己创建的游戏编程源码申请软件著作权详细流程(免费分享模板)

以为我这篇文章制作的游戏申请软件著作权为例 Ren‘py 视觉小说 交互式故事游戏制作过程学习笔记(Windows下实现)(多结局游戏)-CSDN博客 一、网站注册 申请软著时&#xff0c;所有的著作权人都需要在中国版权保护中心官网注册账号&#xff0c;并进行实名认证后&#xff0c;才…

使用WalletConnect Web3Modal v3 链接钱包基础教程

我使用的是vueethers 官方文档&#xff1a;WalletConnect 1.安装 yarn add web3modal/ethers ethers 或者 npm install web3modal/ethers ethers2.引用 新建一个js文件&#xff0c;在main.js中引入&#xff0c;初始化配置sdk import {createWeb3Modal,defaultConfig, } from…

【预计IEEE出版|EI征稿通知】第六届下一代数据驱动网络国际学术会议 (NGDN 2024)

第六届下一代数据驱动网络国际学术会议 (NGDN 2024) The Sixth International Conference on Next Generation Data-driven Networks 2024年4月26-28日 | 中国沈阳 基于前几届在英国埃克塞特 (ISPA 2020) 、中国沈阳 (TrustCom 2021) 和中国武汉 (IEEETrustCom-2022) 成功举…

半监督语义分割综述

paper link&#xff1a;https://arxiv.org/pdf/2302.09899.pdf 1. Introduction 图像分割是最古老、研究最广泛的计算机视觉 (CV) 问题之一。图像分割是指将图像划分为不同的非重叠区域&#xff0c;并将相应的标签分配给图像中的每个像素&#xff0c;最终获得ROI区域位置及其类…

【智能家居】二、添加火灾检测模块(烟雾报警功能点)

可燃气体传感器 MQ-2 和 蜂鸣器 代码段 controlDevice.h&#xff08;设备控制&#xff09;smokeAlarm.c&#xff08;烟雾报警器&#xff09;buzzer.c&#xff08;蜂鸣器&#xff09;mainPro.c&#xff08;主函数&#xff09;运行结果 可燃气体传感器 MQ-2 和 蜂鸣器 代码段 …

基于机器深度学习的交通标志目标识别

在线工具推荐&#xff1a; 三维数字孪生场景工具 - GLTF/GLB在线编辑器 - Three.js AI自动纹理化开发 - YOLO 虚幻合成数据生成器 - 3D模型在线转换 - 3D模型预览图生成服务 智能交通系统&#xff08;ITS&#xff09;&#xff0c;包括无人驾驶车辆&#xff0c;尽管在道路…

OrangePi 5:ROS2 Humble中使用激光雷达

OrangePi 5&#xff1a;ROS2 Humble中使用激光雷达 文章目录 OrangePi 5&#xff1a;ROS2 Humble中使用激光雷达1、硬件准备2、ROS2 Humble安装2.1 使用集成脚本安装2.2 按ROS2官方指导安装2.3 ROS2安装验证 3、YDLIDAR X2激光雷达驱动安装3.1 YDLIDAR X2激光雷达介绍3.2 YDLID…

go第三方包发布(短精细)

1、清除其他依赖项 $ go mod tidy # 清除不必要的依赖依赖清除完成后&#xff0c;查看go.mod文件配置是否规范 module github.com/fyupeng/rpc-go-netty go 1.19 require ( )2、本地版本创建 $ git tag v0.1.0 # 本地 创建标签3、版本提交 $ git push github v0.1.0 # 推送…

Programming Contest 2023(AtCoder Beginner Contest 331)D题 Tile Pattern --- 题解

目录 D - Tile Pattern 题目大意&#xff1a; 思路&#xff1a; 代码&#xff1a; D - Tile Pattern D - Tile Pattern (atcoder.jp) 题目大意&#xff1a; 给你一个n和q&#xff0c;n为局部棋盘大小(n*n) 并且给出局部棋盘中黑白子位置的放置情况&#xff0c;q为查询次数…

Docker部署Plik临时文件上传系统并且实现远程访问

文章目录 1. Docker部署Plik2. 本地访问Plik3. Linux安装Cpolar4. 配置Plik公网地址5. 远程访问Plik6. 固定Plik公网地址7. 固定地址访问Plik8. 结语 本文介绍如何使用Linux docker方式快速安装Plik并且结合Cpolar内网穿透工具实现远程访问&#xff0c;实现随时随地在任意设备上…

深入解析JVM内存结构:Metaspace、堆与垃圾收集器

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…

Flask使用线程异步执行耗时任务

1 问题说明 1.1 任务简述 在开发Flask应用中一定会遇到执行耗时任务&#xff0c;但是Flask是轻量级的同步框架&#xff0c;即在单个请求时服务会阻被塞&#xff0c;直到任务完成&#xff08;注意&#xff1a;当前请求被阻塞不会影响到其他请求&#xff09;。 解决异步问题有…

C语言--每日选择题--Day32

如果大家对读研究生和就业不知道如何抉择&#xff0c;我的建议是看大家的经济基础&#xff0c;如果家里不是很需要你们工作&#xff0c;就读研提升自己的学历&#xff0c;反之就就业&#xff1b;毕竟经济基础决定上层建筑&#xff1b; 第一题 1. 下面代码的结果是&#xff1a;…

Paxos 算法

Paxos 算法 介绍 Paxos 算法是第一个被证明完备的分布式系统共识算法。共识算法的作用是让分布式系统中的多个节点之间对某个提案&#xff08;Proposal&#xff09;达成一致的看法。提案的含义在分布式系统中十分宽泛&#xff0c;像哪一个节点是 Leader 节点、多个事件发生的…