linux_管道学习-pipe函数-管道的读写-fpathconf函数

news/2024/4/24 20:50:46/

接上一篇:linux_何为IPC-进程间常用的通信方式

今天来分享linux的管道学习,希望我的笔记能对大家有用,开始上菜:

目录

  • 1.管道的概念:
  • 2.pipe函数
  • 3.管道的读写行为
  • 4.管道缓冲区大小
  • 5.管道的优劣

1.管道的概念:

  管道是一种最基本的IPC机制,作用于有血缘关系的进程之间,完成数据传递。
  调用pipe系统函数即可创建一个管道。
管道有如下特质:
  1. 其本质是一个伪文件(实为内核缓冲区)
  2. 由两个文件描述符引用,一个表示读端,一个表示写端。
  3. 规定数据从管道的写端流入管道,从读端流出。
什么是有血缘关系的进程: 就是父子进程、兄弟进程等。
管道的原理: 管道实为内核使用环形队列机制,借助内核缓冲区(4k)实现。
512B是磁盘的最小单位,即半k。
管道的局限性:
  ① 数据自己读不能自己写。
  ② 数据一旦被读走,便不在管道中存在,不可反复读取。
  ③ 由于管道采用半双工通信方式。因此,数据只能在一个方向上流动。
  ④ 只能在有公共祖先的进程间使用管道。
管道属于单工通信。

2.pipe函数

函数作用:
  创建一个管道。
头文件:
  #include <unistd.h>
函数原型:
  int pipe(int pipefd[2]);
函数参数:
  pipefd:pipefd[0]为读端,pipefd[1]为写端。
向管道文件读写数据其实是在读写内核缓冲区。
返回值:
  成功:返回0;
  失败:返回-1;会设置errno,通过perror函数来打印错误信息。

  管道创建成功以后,创建该管道的进程(父进程)同时掌握着管道的读端和写端。
  1. 父进程调用pipe函数创建管道,得到两个文件描述符fd[0]、fd[1]指向管道的读端和写端。
  2. 父进程调用fork创建子进程,那么子进程也有两个文件描述符指向同一管道。
  3. 父进程关闭管道读端,子进程关闭管道写端。父进程可以向管道中写入数据,子进程将管道中的数据读出。由于管道是利用环形队列实现的,数据从写端流入管道,从读端流出,这样就实现了进程间通信。

3.管道的读写行为

  使用管道需要注意以下4种特殊情况(假设都是阻塞I/O操作,没有设置O_NONBLOCK标志)(可直接看下方总结):
  1. 如果所有指向管道写端的文件描述符都关闭了(管道写端引用计数为0),而仍然有进程从管道的读端读数据,那么管道中剩余的数据都被读取后,再次read会返回0,就像读到文件末尾一样。

  2. 如果有指向管道写端的文件描述符没关闭(管道写端引用计数大于0),而持有管道写端的进程也没有向管道中写数据,这时有进程从管道读端读数据,那么管道中剩余的数据都被读取后,再次read会阻塞,直到管道中有数据可读了才读取数据并返回。

  3. 如果所有指向管道读端的文件描述符都关闭了(管道读端引用计数为0),这时有进程向管道的写端write,那么该进程会收到信号SIGPIPE,通常会导致进程异常终止。当然也可以对SIGPIPE信号实施捕捉,不终止进程。

  4. 如果有指向管道读端的文件描述符没关闭(管道读端引用计数大于0),而持有管道读端的进程也没有从管道中读数据,这时有进程向管道写端写数据,那么在管道被写满时再次write会阻塞,直到管道中有空位置了才写入数据并返回。

总结:
  ① 读管道:
    1. 管道中有数据,read返回实际读到的字节数。
    2. 管道中无数据:
      (1) 管道写端被全部关闭,read返回0 (好像读到文件结尾)
      (2) 写端没有全部被关闭,read阻塞等待(不久的将来可能有数据递达,此时会让出cpu)
  ② 写管道:
    1. 管道读端全部被关闭, 进程异常终止(也可使用捕捉SIGPIPE信号,使进程不终止)
    2. 管道读端没有全部关闭:
      (1) 管道已满,write阻塞。
      (2) 管道未满,write将数据写入,并返回实际写入的字节数。
例子:

#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>
int main(void)
{pid_t pid;char buf[1024];int fd[2];char *p = "hello pipe!\n";//pipe函数,0读,1写if (pipe(fd) == -1) {perror("pipe");}pid = fork();//创建子进程if (pid < 0) {perror("fork err");} else if (pid == 0) //子进程 读数据{close(fd[1]);//关闭写端for (size_t i = 0; i < 2; i++){printf("------%ld\n",i+1);//从fd中读数据,会在这里阻塞等待读取管道中的数据,直至有数据读取后程序才往下走int len = read(fd[0], buf, sizeof(buf));//将数据写到屏幕中write(STDOUT_FILENO, buf, len);}printf("---------------\n");close(fd[0]);} else {//父进程  写数据close(fd[0]);//关闭读端sleep(2);//暂停2s后才写数据write(fd[1], p, strlen(p));//向fd中写数据sleep(2);//再次暂停2swrite(fd[1], p, strlen(p));//向fd中写数据wait(NULL);//等待回收子进程close(fd[1]);//关闭写端}return 0;
}

4.管道缓冲区大小

  可以使用ulimit –a 命令来查看当前系统中创建管道文件所对应的内核缓冲区大小。
通常为:
   pipe size (512 bytes, -p) 8

函数作用:
  查看管道的大小。
头文件:
  #include <unistd.h>
函数原型:
  long fpathconf(int fd, int name);
函数参数:
fd:
  若需要求出管道的大小,则该fd指向管道。
name:
  将name设置为等于以下常量之一将返回以下配置:
_PC_LINK_MAX
  指向文件的最大链接数。如果fd或path引用一个目录,那么该值将应用于整个目录。相应的宏是_POSIX_LINK_MAX。
_PC_MAX_CANON
  格式化输入行的最大长度,其中fd或path必须指向一个终端。相应的宏是_POSIX_MAX_CANON。
_PC_MAX_INPUT
  输入行的最大长度,其中fd或path必须指向一个端子。相应的宏是_POSIX_MAX_INPUT。
_PC_NAME_MAX
  允许进程创建的目录路径或fd中文件名的最大长度。相应的宏是_POSIX_NAME_MAX。
_PC_PATH_MAX
  当path或fd是当前工作目录时,相对路径名的最大长度。相应的宏是_POSIX_PATH_MAX。
_PC_PIPE_BUF
  可以原子方式写入FIFO管道的最大字节数。对于fpathconf(),fd应该指管道或FIFO。对于fpathconf(),路径应该指向FIFO或目录;在后一种情况下,返回的值对应于在该目录中创建的FIFO。相应的宏是_POSIX_PPIPE_BUF。
_PC_CHOWN_RESTRICTED
  如果使用chown(2)和fchown(2)更改文件的用户ID仅限于具有适当权限的进程,并且将文件的组ID更改为进程的有效组ID或其补充组ID之一以外的值仅限于具有相应权限的进程时,则返回正值。根据POSIX.1,该变量应始终使用-1以外的值进行定义。相应的宏是_POSIX_CHOWN_RESTRECTED。如果fd或path引用了一个目录,那么返回值将应用于该目录中的所有文件。
_PC_NO_TRUNC
  如果访问长度超过_POSIX_NAME_MAX的文件名会产生错误,则返回非零。相应的宏是_POSIX_NO_TRUNC。
_PC_VDISABLE
  如果可以禁用特殊字符处理,则返回非零,其中fd或path必须指代终端。指向文件的最大链接数。如果fd或path引用一个目录,那么该值将应用于整个目录。相应的宏是_POSIX_LINK_MAX。

返回值:
  成功:根据不同的name返回不同的值。
  失败:-1,设置errno
例如:
  long lsize = fpathconf(fd[0], _PC_PIPE_BUF);//获得管道的大小

5.管道的优劣

  优点:简单,相比信号,套接字实现进程间通信,简单很多。
  缺点:
    1. 只能单向通信,双向通信需建立两个管道。
    2. 只能用于父子、兄弟进程(有共同祖先)间通信。该问题后来使用fifo有名管道解决。

以上就是本次的分享了,希望能对广大网友有所帮助,也希望大家踊跃讨论,相互学习。

此博主在CSDN发布的文章目录:【我的CSDN目录,作为博主在CSDN上发布的文章类型导读】


http://www.ppmy.cn/news/47472.html

相关文章

云通讯服务商有哪些?

随着语聊、视频通话、直播等行业的兴起&#xff0c;云通讯厂商的作用越来越凸显&#xff0c;解决画面卡顿、解决声音延迟以及基于互动领域更多的行业解决方案已经成为开发者和企业所需。 从长远来看&#xff0c;随着5G的不断普及&#xff0c;低延迟、高质量的网络环境不断催生线…

kafka--python

文章目录 1、kafka是什么2、docker上部署kafka3、在kafka容器内部署python&#xff0c;并跑通生产者-消费者简单代码4、最新接口4.1、kafka_config.py4.2、kafka_interface.py4.3、run.py4、测试 1、kafka是什么 Producer&#xff1a;即生产者&#xff0c;消息的产生者&#xf…

编译和引用so库

编译和引用so库 1.两种编译方式 ndk-build Android.mk Application.mkCMake CMakeList 2.Android.mk Application.mk (1)javac java文件的绝对路径 → 生成so库 (2)javah com.xxx.xxx.tesAdd → 生成头文件 (3) 修改头文件的后缀&#xff0c;并添加实现 (4)Applicat…

git教程

Git是目前最流行的分布式版本控制系统之一&#xff0c;它可以帮助开发者更好地管理代码和协作开发。以下是Git教程的一些内容&#xff1a; Git入门&#xff1a;介绍Git的基本概念、Git工作流程和Git常用命令。 Git分支&#xff1a;讲解Git分支的用法&#xff0c;包括新建分支、…

Flutter与Android开发:构建跨平台移动应用的新选择

Flutter与Android开发&#xff1a;构建跨平台移动应用的新选择 本文内容提纲如下&#xff1a; 介绍Flutter技术&#xff1a;Flutter是一种由Google推出的开源UI工具包&#xff0c;用于构建高性能、跨平台的移动应用。文章将介绍Flutter的基本概念、特点和优势&#xff0c;包括其…

Python面向对象详解(非常详细)

非常详细的讲解&#xff08;爆肝1w字&#xff09;&#x1f44f;&#x1f3fb;&#x1f44f;&#x1f3fb;&#x1f44f;&#x1f3fb; 零基础一样学得会&#x1f44c;&#x1f3fb; 干货满满不看后悔&#x1f44d;&#x1f44d;&#x1f44d; &#x1f4dd;个人主页→数据…

可能你已经刷了很多01背包的题,但是真的对01背包领悟透彻了吗?,看我这一篇,使君对01背包的理解更进一步【代码+图解+文字描述】

一.概念理解&#xff1a;什么是01背包 关于01背包的概念理解如下&#xff1a;01背包是在M件物品取出若干件放在空间为W的背包里&#xff0c;每件物品的体积为W1&#xff0c;W2至Wn&#xff0c;与之相对应的价值为P1,P2至Pn。001背包的约束条件是给定几种物品&#xff0c;每种物…

数组篇刷题总结

二分查找&#xff1a; 给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组 nums 和一个目标值 target &#xff0c;写一个函数搜索 nums 中的 target&#xff0c;如果目标值存在返回下标&#xff0c;否则返回 -1。 示例 1: 输入: nums [-1,0,3,5,9,12], target …

win11下载配置Python环境+pycharm下载

前两天快乐的把我重装的win10升级成win11&#xff0c;升级的时候超怕不能成功&#xff0c;但效果还不错&#xff0c;然后突然想学一学Python&#xff0c;所以首先来配置环境吧 一、下载安装包 建议去官网&#xff0c;因为自从有了Python3之后&#xff0c;Python2就慢慢的被淘汰…

Difference between HTTP3 and HTTP2

HTTP3目前还在不断更新中。一般每个新版本的优化&#xff0c;都会主要针对上一个版本的缺点。 对HTTP2&#xff0c;有二进制编码、头部压缩、多路复用、服务器推送等新特性去弥补了HTTP1.1中的不足。不过HTTP2基于TCP实现的&#xff0c;带3个缺陷&#xff1a;① TCP层面的队头阻…

常见的注册中心Nacos、Eureka

常见的注册中心 1.Eureka&#xff08;原生&#xff0c;2.0遇到瓶颈&#xff0c;停止维护&#xff09; 2.Zookeeper&#xff08;支持&#xff0c;专业的独立产品。例如&#xff1a;dubbo&#xff09; 3.Consul&#xff08;原生&#xff0c;GO语言开发&#xff09; 4.Nacos …

Vue CLI 浏览器兼容性

Vue CLI 浏览器兼容性 browserslist 你会发现有 package.json 文件里的 browserslist 字段 (或一个单独的 .browserslistrc 文件)&#xff0c;指定了项目的目标浏览器的范围。这个值会被 babel/preset-env 和 Autoprefixer 用来确定需要转译的 JavaScript 特性和需要添加的 CS…

康耐视Designer,通过VC5与西门子S7-1200 PLCProfinet通讯详细

测试使用软件版本 Designer Version: 2.7 GSD: GSDML-V2.3-Cognex-VC5-20140828STEP 7 Professional V14Network Configurator Version: 3.56测试使用硬件 Cognex Vision Controller VC5CIC-5000Siemens PLC: S7-1200 CPU 1214C DC/DC/RLY1.PLC端设置 1.新建一个项目,添加对应…

WxGL应用实例:绘制高精度的3D太阳系模型

文章目录 1 坐标系的选择1.1 黄道坐标系1.2 三维空间直角坐标系 2 使用JPL星历表计算轨道2.1 日期时间2.2 特定时刻天体的位置2.3 天体运行轨道 3 太阳系模型3. 1 全家福3.2 时间、距离和半径的缩放3.3 黄道坐标系模型 天何所沓&#xff1f;十二焉分&#xff1f;日月安属&#…

做好Python工程师,首先你需要做好的几件事

做好Python工程师&#xff0c;需要做好的几件事&#xff0c;我想分享给大家。首先千万不要做事周折。在你提问之前&#xff0c;先好好想一想&#xff0c;这个问题自己能不能解决。如果能解决&#xff0c;尽量自己解决&#xff1b;如果解决不了&#xff0c;那就要把你的问题描述…

开发方案/红外线人体体温计方案

红外线人体测温仪&#xff0c;是一款非常不错的测温设备&#xff0c;他可以适用于多种场合&#xff0c;尤其是在疫情期间&#xff0c;很多场所都需要这种设备&#xff0c;不管是学校、企业、商场、小区还是机关单位&#xff0c;都需要这种设备。 红外人体测温仪测量距离可在1-5…

etcd v3使用示例

1.简单使用 1.1 增加 set 指定某个键的值。例如: $ etcdctl set /testdir/testkey "Hello world" Hello world 复制代码支持的选项包括&#xff1a; --ttl 0 该键值的超时时间(单位为秒)&#xff0c;不配置(默认为0)则永不超时 --swap-with-value value 若该键现…

ubuntu安装V2board宝塔面板教程

ubuntu安装V2board宝塔面板教程 运行环境:ubuntu-20.04 搭建宝塔web页面环境 切到linux服务器命令行 在用户目录下创建BT目录,进入BT目录 在BT目录下执行命令 sudo wget -O install.sh http://download.bt.cn/install/install-ubuntu_6.0.sh && sudo sh install.sh…

面试题30天打卡-day06

1、什么是反射机制&#xff1f;说说反射机制的优缺点、应用场景&#xff1f; 反射机制&#xff1a;Java的反射机制是在运行状态&#xff0c;对于任意一个类&#xff0c;都能够动态的获得这个类的属性和方法&#xff1b;对于一个对象&#xff0c;都能动态的调用它当中的方法和属…

几十个简要的游戏案例分析

文章目录 一、 介绍二、 影响游戏体验的因素三、 游戏能爆火的因素1.影响游戏爆火因素的排名2.玩游戏的两种经典心理3.经典案例分析Qq农场植物大战僵尸水果忍者召唤神龙羊了个羊 4.游戏公司可借鉴的经验 四、 几十款游戏的多方面分析FC红白游戏机十二人街霸热血高校系列魂斗罗系…