linux 匿名管道 pipe

  

  • 专栏内容:linux下并发编程
  • 个人主页:我的主页
  • 座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物.

目录

前言

概述

原理介绍

接口说明

pipe 与 fifo的区别

代码演示

结尾


前言

本专栏主要分享linux下并发编程相关知识,包括多进程,多线程,进程/线程间通信,并发同步控制,以及高并发下性能提升,请大家多多留言。


概述

管道是在进程间进行通信的一种方式。在不同进程和程序间如何传递少量数据,且能阻塞形式使用,这就用到了管道。管道分为两种,无名管道和命名管道,因为子进程可以复制父进程的进程上下文,所以无名管道用在父子进程间,而命名管道在不同进程间通过路径名进行共享,更加通用。

原理介绍

  • 基本原理

        无名管道是一种在内存中创建的管道,只能在相关进程间使用。它提供一种字节流的通信方式,内容没有边界,所以调用者来控制读写频次。

        一个无名管道是由两个文件描述符表示的,它们都是整数值。一个文件描述符用于读取管道的内容,另一个用于写入管道的内容。如果一个进程向管道写入数据,那么数据就会被暂存到管道中,等待另一个进程来读取。

        使用无名管道进行进程间通信非常方便,使用简单的 read 和 write 系统调用就可以完成,不过需要注意管道大小的限制,一般情况下我们要先创建一个缓存区来存储管道中的内容以及控制读写操作的并发性, 在使用时需要注意管道的关闭和错误处理问题。

        总的来说,无名管道是一种非常实用的进程间通信方式,能够帮助我们完成简单且高效的进程间信息交换。

  • Pipe大小限制

Linux的管道实际上是由缓冲区组成的,管道缓冲区的大小是由内核参数决定的,并没有确定的限制。在内核版本2.6.35以前,管道的缓冲区大小默认是4KB;从2.6.35开始,缓冲区大小被改为了16KB,这是因为在对大型文件进行复制时,较大的缓冲区可以减少CPU使用率,提高复制速度。

pipe大小可以通过proc下的参数进行查询:

 /proc/sys/fs/pipe-max-pages (only in Linux 2.6.34)

/proc/sys/fs/pipe-max-size (since Linux 2.6.35)

 /proc/sys/fs/pipe-user-pages-hard (since Linux 4.5)

 /proc/sys/fs/pipe-user-pages-soft (since Linux 4.5)

设置pipe大小可以用  fcntl的F_GETPIPE_SZ 和F_SETPIPE_SZ来获取和设置。

  • 非阻塞模式

        pipe默认是阻塞模式,写端写入数据,要等读端来读。当然也可以设置为非阻塞模式,通过fcntl的F_SETFL 操作设置参数为 O_NONBLOCK。此时写端直到写满缓冲区时就会失败,其它时候都可以立即返回,读端每次都会立即返回。

接口说明

(1)创建管道

  #include <unistd.h>

  int pipe(int pipefd[2]);

这里会创建一个pipefd的数组,其中pipefd[0]是读端,只能读数据,pipefd[1]是写端,只能用于写数据。

在子进程中,创建后会关闭一端,一个进程只保留一个端(写或读)。

还可以用下面的接口

       #define _GNU_SOURCE             /* See feature_test_macros(7) */

       #include <fcntl.h>              /* Obtain O_* constant definitions */

       #include <unistd.h>

       int pipe2(int pipefd[2], int flags);

flag可以为:

O_CLOEXEC ,这个参数非常有用,当进程调用exec系列接口时,句柄就会自动关闭回收。否则就有资源泄漏。

O_NONBLOCK,非阻塞模式;

(2)管道的读/写

读/写调用 read/write即可

(3)管道的关闭

close(fd)

  • 注意事项

(1)当所有进程关闭了写端时,读端读时就会返回0;当所有进程都关闭了读端时,写端写时就会返回错误,错误码为EPIPE;

(2)关联进程,需要关闭不用的写端或读端,这样才能确保有正确的 SIGPIPE/EPIPE,或是读返回0,收到对端关闭的信息;

pipe 与 fifo的区别

它们的创建和打开方式不同,读写操作是相似的。它们都是通过共享缓冲区,虽然fifo有创建管道文件,并不会与磁盘交互;这两种方式仅是提供缓冲区的读写端。

代码演示

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main()
{
        int fd[2];
        pid_t pid1, pid2;
        if (pipe(fd) == -1)
        {
                fprintf(stderr, "Pipe failed");
                return 1;
        }
        pid1 = fork();
        if (pid1 < 0)
        {
                fprintf(stderr, "Fork failed");
                return 1;
        }
        if (pid1 == 0)
        {
                // Child process 1
                char message[] = "Hello from child process 1!\n";
                close(fd[0]);
                write(fd[1], message, strlen(message));
                close(fd[1]);
                exit(0);
        }
        else
        {
                pid2 = fork();
                if (pid2 < 0)
                {
                        fprintf(stderr, "Fork failed");
                        return 1;
                }
                if (pid2 == 0)
                {
                        // Child process 2
                        char message[] = "Hello from child process 2!\n";
                        close(fd[0]);
                        write(fd[1], message, strlen(message));
                        close(fd[1]);
                        exit(0);
                }
                else
                {
                        // Parent process
                        close(fd[1]);
                        char buffer[100];
                        read(fd[0], buffer, 100);
                        printf("%s", buffer);
                        read(fd[0], buffer, 100);
                        printf("%s", buffer);
                        close(fd[0]);
                }
        }
        return 0;
}

运行结果

[senllang@localhost pipetest]$ gcc pipetest.c -o pipetest
[senllang@localhost pipetest]$ ./pipetest
Hello from child process 1!
Hello from child process 2!


结尾

作者邮箱:study@senllang.onaliyun.com
如有错误或者疏漏欢迎指出,互相学习。另外有什么想要了解的内容,也可以给我发邮件,互相谈讨,定知无不言。

注:未经同意,不得转载!

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

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

相关文章

【K8S系列】深入解析无状态服务

目录 序言 1. 无服务介绍 1.1 优点 1.2 使用场景 1.3 资源类型 1.4 总结 2 使用介绍 2.1 Deployment 使用场景&#xff1a; 2.2 ReplicaSet 使用场景 2.3 pod Pod 资源定义示例 2.4 service 创建一个Deployment&#xff1a; 创建一个Service&#xff1a; 总结…

ChatGPT,让程序员从一片黑暗森林奔向另一片黑暗森林!

几年前看过一个电影&#xff0c;叫做《隐藏人物》&#xff0c;主要讲三位女性在NASA工作时反抗“种族歧视”和“性别歧视”的故事&#xff0c;其中有个情节让我印象极其深刻&#xff1a;NASA计算部门有一群女生&#xff0c;她们的工作是计算飞船轨道&#xff0c;纯手工计算。某…

【算法基础】(一)基础算法 --- 离散化

✨个人主页&#xff1a;bit me ✨当前专栏&#xff1a;算法基础 &#x1f525;专栏简介&#xff1a;该专栏主要更新一些基础算法题&#xff0c;有参加蓝桥杯等算法题竞赛或者正在刷题的铁汁们可以关注一下&#xff0c;互相监督打卡学习 &#x1f339; &#x1f339; &#x1f3…

软件测试,自学3个月出来就是高薪工作?你以为还是2019年以前?

朋友&#xff0c;作为一个曾经从机械转行到IT的行业的过来人&#xff0c;已在IT行业工作4年&#xff0c;分享一下我的经验&#xff0c;供你参考。 讲真&#xff0c;现在想通过培训班培训几个月就进入IT行业&#xff0c;越来越来难了&#xff1b;如果是在2018年以前&#xff0c;…

Spark 算子

目录 什么是Spark rdd算子 算子的分类 Transformation算子 Action算子 转换算子 Value类型 map mapPartitions mapPartitionsWithIndex glom groupBy filter sample distinct coalesce sortBy 双Value类型 intersection union subtract zip K-V类型 par…

【Java基础】-【SpringMVC】

目录什么是MVC&#xff1f;DAO层是做什么的&#xff1f;Spring MVC的执行流程Spring MVC常用注解Spring MVC的拦截器怎么去做请求拦截&#xff1f;其他cookie和session的区别cookie和session各自适合的场景session的工作原理get请求与post请求的区别get请求的参数能放到body里面…

JAVASE基础(一)

这里写目录标题一、javaSE基础1.jdk文档2.代码量统计工具3.文档注释4.反编译工具5.JDK、JRE、JVM&#xff08;java虚拟环境&#xff09;*6.变量命名规则7.变量的作用域8.数据类型9.进制10.反汇编器javap一、javaSE基础 1.jdk文档 Overview (Java Platform SE 8 ) (oracle.com…

stable-diffusion安装和简单测试

参考&#xff1a; https://github.com/CompVis/stable-diffusion 理解DALLE 2&#xff0c; Stable Diffusion和 Midjourney的工作原理 Latent Diffusion Models论文解读 【生成式AI】淺談圖像生成模型 Diffusion Model 原理 【生成式AI】Stable Diffusion、DALL-E、Imagen 背後…

面向对象编程(基础)3:对象的内存解析

目录 3.1 JVM内存结构划分 3.2 对象内存解析 举例&#xff1a; 内存解析图&#xff1a; 面试题&#xff1a;对象名中存储的是什么呢&#xff1f; 3.3 练习 3.1 JVM内存结构划分 HotSpot Java虚拟机的架构图如下。其中我们主要关心的是运行时数据区部分&#xff08;Runtime …

python字符编码

目录 ❤ 前言 文本编辑器存取文件的原理&#xff08;nodepad&#xff0c;pycharm&#xff0c;word&#xff09; python解释器执行py文件的原理 &#xff0c;例如python test.py 总结 ❤ 什么是字符编码? ASCII MBCS Unicode ❤ 字符编码的发展史 阶段一: 现代计算…

vue - vue中混入mixin的使用

vue中mixin混入的使用1&#xff0c;概念2&#xff0c;使用场景3&#xff0c;开始使用4&#xff0c;局部混入和全局混入5&#xff0c;总结1&#xff0c;概念 官方解释&#xff1a; 混入 (mixin) 提供了一种非常灵活的方式&#xff0c;来分发 Vue 组件中的可复用功能。一个混入对…

Python 自动化指南(繁琐工作自动化)第二版:十七、计时、安排任务和启动程序

原文&#xff1a;https://automatetheboringstuff.com/2e/chapter17/ 坐在电脑前运行程序是没问题的&#xff0c;但让程序在没有你直接监督的情况下运行也很有用。您计算机的时钟可以安排程序在某个指定的时间和日期或定期运行代码。例如&#xff0c;你的程序可以每小时抓取一个…

Python 自动化指南(繁琐工作自动化)第二版:十三、使用 EXCEL 电子表格

原文&#xff1a;https://automatetheboringstuff.com/2e/chapter13/ 虽然我们不经常将电子表格视为编程工具&#xff0c;但几乎每个人都使用它们将信息组织成二维数据结构&#xff0c;用公式执行计算&#xff0c;并以图表的形式产生输出。在接下来的两章中&#xff0c;我们将把…

Window10平台下编译Sqlite3.4

1、下载网址&#xff1a;SQLite Download Page 需要下载如下内容&#xff1a; 我这里下载64位的dll 2、我用的vs2019新建一个windows桌面项目&#xff0c;应用程序类型:动态链接库(.dll),空项目&#xff1a; 3、将如下文件复制到工程目录下&#xff0c;然后添加到工程中 添加到…

动力节点老杜Vue笔记——Vue程序初体验

目录 一、Vue程序初体验 前言 1.1 下载并安装vue.js 1.2 第一个Vue程序 1.3 Vue的data配置项 1.4 Vue的template配置项 一、Vue程序初体验 前言 可以先不去了解Vue框架的发展历史、Vue框架有什么特点、Vue是谁开发的&#xff0c;这些对我们编写Vue程序起不到太大的作…

koa开发实践2:为koa项目添加路由模块

nodeJS server-side-developkoa开发实践2&#xff1a;为koa项目添加路由模块上一节&#xff1a;《 koa开发实践2&#xff1a;为koa项目添加路由模块 》| 下一节&#xff1a;《 koa开发实践3&#xff1a;在koa项目中使用 swagger 文档 》作者&#xff1a; 李俊才&#xff1a;…

哪些是真正的全光谱灯品牌呢?推荐五款全光谱护眼灯

所谓全光谱&#xff0c;就是指灯光的色谱成分无限接近太阳光的色谱成分。我们都知道&#xff0c;太阳光不单单只有一束简单的白光&#xff0c;而是有很多种颜色的单色光复合而成&#xff0c;所以它的色彩显色效果非常丰富、真实&#xff0c;这些单色光也成了太阳光的色谱成分。…

浅谈机器学习--聚类

还不了解机器学习&#xff1f;来看&#xff01; 目录 一.聚类 二.k均值聚类算法(k-means) 1.k均值聚类算法的流程 二.k均值算法的改进 1.二分k-means算法 2.k-means算法 3.k-medoids算法 4.Mini Batch k-means算法 三.DBSCAN算法 1.​编辑-邻域 2.核心点和边界点 …

关于TextureRender适配的解决方案

当我们用摄像机渲染出一个图片&#xff0c;显示在UI的时候&#xff0c;会发现&#xff0c;你如果自适配&#xff0c;那么就会拉伸图片&#xff0c;导致人物或者场景变形。 我最近就遇到了这个事&#xff0c;这里我给出几种问题和解决方案&#xff1a; 1 &#xff1a;当我们想…

NSSCTF Round#11 --- 密码个人赛 wp

文章目录ez_encMyMessageMyGameez_signinez_facez_enc 题目&#xff1a; ABAABBBAABABAABBABABAABBABAAAABBABABABAAABAAABBAABBBBABBABBABBABABABAABBAABBABAAABBAABBBABABABAAAABBAAABABAABABBABBBABBAAABBBAABABAABBAAAABBBAAAABAABBBAABBABABAABABAAAAABBBBABAABBBBAAAAB…