Linux进程通信之管道

目录

1、无名管道

1.无名管道的特点

2.pipe函数创建管道

3.图例 

  

2、命名管道(FIFO)

1.命名管道的特点

2.mkfifo 函数-创建命名管道

 3.示例

1.循环读取数据

2.循环写入数据


1、无名管道

管道通常指的就是无名管道,

1.无名管道的特点

  1. 管道是半双工的,只支持数据的单向传输,有固定的读端和写端。
  2. 无名管道用于有亲缘关系的进程间通信
  3. 无名管道可以看作一种特殊的文件,对它的读写我们可以直接使用普通的read、write等函数进行操作,但是注意无名管道并不是普通的文件,它不存在任何的文件系统中,只存在于内存中
  4. 管道里的数据被读走了就会从管道中消失

2.pipe函数创建管道

pipe 函数是用于创建管道的系统调用,通常用于在父子进程之间进行单向通信

函数原型

int pipe(int pipefd[2]);

参数:

  • pipefd: 一个包含两个文件描述符的整数数组,pipefd[0] 用于读取数据,pipefd[1] 用于写入数据。

返回值:

  • 如果成功,返回 0。
  • 如果失败,返回 -1,并设置 errno 指示错误类型。

pipe函数会创建两个文件描述符,pipefd[0]是读端、pipefd[1]是写端

需要注意的是,pipe 函数创建的管道是阻塞的,如果管道已满(写端写入速度过快),写操作将会被阻塞,直到有空间可用

3.图例 

  

如果要使数据从父进程流向子进程就需要关闭父进程的读端和子进程的写端,反之就使数据从子进程流向父进程 

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>

int main() {
    int fd[2];            // 用于存储管道的文件描述符,fd[0] 为读取端,fd[1] 为写入端
    int pid;              // 用于存储 fork 函数的返回值,表示当前是父进程还是子进程
    char buf[128] = {0};  // 用于存储从管道中读取的数据

    // 创建管道
    if (pipe(fd) == -1) {
        printf("pipe 创建失败\n");
        perror("pipe");
        exit(-1);  // 如果 pipe 创建失败,退出程序,返回 -1
    }

    // 创建子进程
    pid = fork();
    if (pid < 0) {
        printf("fork 创建失败\n");
        perror("fork");
        exit(-1);  // 如果 fork 创建失败,退出程序,返回 -1
    } else if (pid > 0) {  // 父进程
        printf("parent process\n");

        close(fd[0]);  // 关闭读取端,因为父进程只负责写入数据
        write(fd[1], "holle wjh happy", strlen("holle wjh happy"));  // 向管道写入数据
        wait(NULL);  // 等待子进程结束

    } else {  // 子进程
        printf("child process\n");

        close(fd[1]);  // 关闭写入端,因为子进程只负责读取数据
        read(fd[0], buf, 128);  // 从管道读取数据到 buf 中
        printf("read: %s\n", buf);

        exit(0);  // 子进程正常结束,返回 EXIT_SUCCESS
    }

    return 0;
}

2、命名管道(FIFO)

命名管道(Named Pipe)是一种特殊类型的管道,与无名管道(通过 pipe 创建的)不同,它具有文件系统中的名字,并且可以通过文件系统路径来访问。命名管道在进程间通信中提供了一种有趣而强大的方式。

1.命名管道的特点

  1. 命名管道是通过在文件系统中创建一个具有名字的特殊文件来实现的。这个文件的路径就是命名管道的名字
  2. 命名管道的使用方式与文件类似,可以使用标准的文件读写操作函数来进行进程间通信。打开命名管道后,可以使用 readwrite 等函数进行数据传输。
  3. 命名管道常用于独立的进程之间通信。在这种情况下,各个进程可以通过打开相同路径名的命名管道文件来进行通信,也就是说命名管道可以在无关进程之间进行通信,这里和无名管道不同
  4. 像无名管道一样,命名管道的读写操作也是阻塞的。如果没有数据可读,读取操作会被阻塞,直到有数据为止;如果管道已满,写入操作会被阻塞,直到有空间可用。

2.mkfifo 函数-创建命名管道

函数原型

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

mkfifo是 "make FIFO" 的缩写,用于创建一个新的命名管道

参数:

  • pathname:要创建的命名管道的路径名。
  • mode:创建的文件权限。通常使用八进制表示,例如 0666

返回值:

  • 如果成功创建命名管道,返回 0。
  • 如果失败,返回 -1,并设置 errno 表示具体的错误类型。

注意:

  • 在成功创建命名管道后,可以使用标准的文件操作函数(如 openreadwrite 等)来进行读写操作。
  • 如果已经存在同名的普通文件或目录,mkfifo 会失败。

 3.示例

1.循环读取数据
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>

int main() {
    char buf[30] = {0};

    // 尝试创建命名管道
    if (mkfifo("./file", 0600) == -1 && errno != EEXIST) {
        printf("mkfifo 失败!!!\n");
        perror("mkfifo");
        exit(EXIT_FAILURE);
    } else if (errno == EEXIST) {
        perror("mkfifo");
        // 如果管道已经存在,继续执行
    }

    // 打开命名管道进行读取
    int fd = open("./file", O_RDONLY);
    if (fd == -1) {
        printf("open 失败!!!\n");
        perror("open");
        exit(EXIT_FAILURE);
    } else {
        // 循环读取数据
        while (1) {
            int read_count = read(fd, buf, 20);
            if (read_count > 0) {
                printf("read_count = %d, reads = %s\n", read_count, buf);
            } else if (read_count == 0) {
                // 如果 read 返回 0,表示已经读到文件末尾,可以采取适当的处理方式
                printf("End of file reached. Exiting...\n");
                break;
            } else {
                // 处理 read 函数返回的错误
                perror("read");
                break;
            }
        }
        // 关闭文件描述符
        close(fd);
    }

    return 0;
}
2.循环写入数据
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main() {
    // 创建一个名为 "file" 的命名管道
    if (mkfifo("./file", 0600) == -1 && errno != EEXIST) {
        // 如果创建失败且不是因为文件已存在,则输出错误信息并退出程序
        printf("mkfifo 失败!!!\n");
        perror("mkfifo");
        exit(EXIT_FAILURE);
    } else if (errno == EEXIST) {
        // 如果管道已经存在,则输出相应的错误信息
        perror("mkfifo");
    }

    // 打开命名管道进行写入
    int fd = open("./file", O_WRONLY);
    if (fd == -1) {
        // 如果打开失败,则输出错误信息
        perror("open");
    } else {
        // 在循环中每秒写入一次数据到管道中
        while (1) {
            sleep(1);
            int write_count = write(fd, "happy bay wjh", strlen("happy bay wjh"));
            printf("write_count = %d\n", write_count);
        }

        // 关闭文件描述符
        close(fd);
    }

    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

校招行测,认知能力测验,④破解数量关系测试题

数量关系&#xff0c;值得是数量计算、对比和分析&#xff0c;每种题型都有一定的规律性&#xff0c;如果善于终结也是容易掌握的&#xff0c;当然&#xff0c;只有见多&#xff0c;才能识广&#xff0c;最好的方式就是&#xff0c;锻炼&#xff0c;刷题&#xff0c;就算是临时…

3D Web可视化开发工具包HOOPS Communicator:提供Web端浏览大型模型新方案!

前言&#xff1a;HOOPS Communicator是Tech Soft 3D旗下的主流产品之一&#xff0c;具有强大的、专用的高性能图形内核&#xff0c;专注于基于Web的高级3D工程应用程序。其由HOOPS Server和HOOPS Web Viewer两大部分组成&#xff0c;提供了HOOPS Convertrer、Data Authoring的模…

类和对象的定义以及使用

文章目录 1. 类和对象的基本概念1.1 JAVA是面向对象语言1.2 类和对象的描述 2. 类与对象的定义与使用2.1 类的定义格式2.2 类的实例化(对象的创建)2.3 举个例子 3. 对象的构造及初始化3.1构造方法3.1.1构造方法的定义3.1.2 构造方法的特性 4.2 默认初始化5.4 就地初始化 4.this…

九州金榜如何让孩子在家庭教育中更优秀

​ 每个人在出生时就有上天恩赐的两份礼物&#xff0c;一份是血脉相连的亲情&#xff0c;一份是家庭的关爱与教育。 最早接触的人就是父母&#xff0c;最早接触的教育就是家庭教育&#xff0c;这对孩子的影响极为深远。 这种家庭教育相比较学校教育&#xff0c;不仅有言传教…

认知能力测验,⑤破解图形推理测试题,校招社招网申在线测评必用

认知能力测试&#xff0c;如今是每个求职者必须要面对的&#xff0c;有的人可以顺顺利利通过&#xff0c;而有的人只能够遗憾止步。想要通过认知能力测验&#xff0c;并不是一件易事&#xff0c;而今天要说的图形推理&#xff0c;仅仅是其中的一个部分&#xff0c;抛砖引玉&…

2024.01.09.Apple_UI_BUG

我是软件行业的&#xff0c;虽然不是手机设计的&#xff0c;但是这个设计真的导致经常看信息不完整&#xff0c;要下拉的。 特别读取文本或者其他文件的时候&#xff0c;上面有个抬头就是看不到&#xff0c;烦&#xff0c;体验感很差

Requests库的接口测试实现

Requests库是在接口测试中被广泛运用的库&#xff0c;包括模拟请求的下发&#xff0c;请求相关配置和响应结果的获取&#xff0c;核心主体都是通过request库完成。在接口测试中使用非常频繁。 一、Requests库环境搭建 接口测试的核心从模拟请求开始。在Python中&#xff0c;通…

机器学习:数据处理与特征工程

机器学习中的数据处理和特征工程是非常关键的步骤&#xff0c;它们直接影响模型的性能和泛化能力。以下是一些常见的数据处理和特征工程技术&#xff1a; 数据处理&#xff1a; 缺失值处理&#xff1a; 处理数据中的缺失值&#xff0c;可以选择删除缺失值、填充均值/中位数/众…

HarmonyOS应用开发学习笔记 ArkTS 布局概述

一、布局概述 布局指用特定的组件或者属性来管理用户页面所放置UI组件的大小和位置。在实际的开发过程中&#xff0c;需要遵守以下流程保证整体的布局效果 确定页面的布局结构。分析页面中的元素构成。选用适合的布局容器组件或属性控制页面中各个元素的位置和大小约束。 二…

HarmonyOS应用开发学习笔记 UIAbility组件间交互 UIAbility启动,页面跳转结果回调

1、 HarmoryOS Ability页面的生命周期 2、 Component自定义组件 3、HarmonyOS 应用开发学习笔记 ets组件生命周期 4、HarmonyOS 应用开发学习笔记 ets组件样式定义 Styles装饰器&#xff1a;定义组件重用样式 Extend装饰器&#xff1a;定义扩展组件样式 5、HarmonyOS 应用开发…

(生物信息学)R语言绘图初-中-高级——3-10分文章必备——饼图(初级)

生物信息学文章的发表要求除了思路和热点以外,图片绘制是否精美也是十分重要的,本专栏为(生物信息学)R语言绘图初-中-高级——3-10分文章必备,主要通过大量文献,总结3-10分文章中高频出现的各种图片,并给大家提供图片复现的R语言代码,及图片识读。 本专栏将向大家介绍…

你好,2024!再见,2023!

大家好&#xff0c;我是南城余&#xff01; 今天是2023年最后一天&#xff0c;看到各位大佬都在分享今年的总结&#xff0c;我也来做个年度总结&#xff0c;是第一次做年度总结&#xff0c;希望以后可以每年都做一个好好的回顾。 说来可笑&#xff0c;标题&#xff0c;2023怎么…

Maven 工程 java -jar 时提示 xxx-SNAPSHOT.jar 中没有主清单属性

Maven 工程 java -jar 时提示 xxx-SNAPSHOT.jar 中没有主清单属性 将skip属性注释掉或者改为false 如果为true&#xff0c;则工程找不到主启动类

Pytest插件pytest-cov:优雅管理测试覆盖率

在软件开发中&#xff0c;测试覆盖率是评估测试质量的关键指标之一。为了更方便地统计和管理测试覆盖率&#xff0c;Pytest插件"pytest-cov"应运而生。本文将介绍"pytest-cov"的基本用法和优雅管理测试覆盖率的方法。 什么是pytest-cov? pytest-cov 是Pyt…

zabbix-proxy代理安装及其他监控方式

zabbix-proxy代理安装及其他监控方式 安装zabbix-proxyserver端配置zabbix-proxy配置被监控的agent安装中问题解决监控网络设备JMX和IPMI监控方式 zabbix-proxy的安装&#xff0c;至少需要准备三台机器&#xff0c;一台安装服务端&#xff0c;一台安装agent端&#xff0c;这里就…

65寸OLED透明拼接屏,从这4个方面解读,让您秒懂

随着显示技术的不断进步&#xff0c;OLED透明拼接屏作为新一代的大屏显示解决方案&#xff0c;正逐渐受到市场的青睐。作为尼伽技术总监&#xff0c;我深知其对于高端显示市场的价值。下面&#xff0c;我将从技术的角度深入剖析这一产品。 一、规格与种类 65寸OLED透明拼接屏有…

Java学习笔记-day03-类名.this:内部类引用外部类实例

类名.this是啥意思&#xff1f; 今天在看尚硅谷的课程时里面讲了这么一句话&#xff1a; 集合在遍历时需要先创建一个容器&#xff0c;存放集合的数据&#xff0c;这样做浪费内存 想去验证下&#xff0c;就翻了翻ArrayList的迭代过程源码 在ArrayList的迭代器类Itr&#xff08;…

在 PyCharm 中使用 Copilot

GitHub Copilot 由 OpenAI Codex 提供支持&#xff0c;可帮助用户在编辑器中实时工作。 它使用强大的 GPT-3 模型版本&#xff0c;该模型在大量开源代码上进行训练。 此外&#xff0c;GitHub Copilot 可在不同的 IDE&#xff08;集成开发环境&#xff09;上使用&#xff0c;包…

局域网IP地址冲突、环路的罪魁祸首是什么?

中午好&#xff0c;我的网工朋友。 这个时代&#xff0c;网络已经贯穿了人们的生活&#xff0c;对企业而言&#xff0c;办公信息化更是离不开网络支持。 为了提高安全管理和信息化水平&#xff0c;很多企业都建立了完善的办公信息系统&#xff0c;但一些企业在网络建设方面还…

【嵌入式】git工具基础命令学习笔记 | 嵌入式Linux

文章目录 前言一、git基础指令二、git分支管理2.1、一些基础命令2.2、时间回溯2.3、新建分支&#xff0c;删除分支&#xff0c;重命名分支 前言 参考&#xff1a;飞凌嵌入式ElfBoard ELF-1 软件学习手册 chatGPT 一、git基础指令 首先我们新建一个名叫git的文件夹&#xff0…