首页 > 其他分享 >匿名管道

匿名管道

时间:2023-10-29 12:13:05浏览次数:27  
标签:文件 表项 管道 匿名 关闭 进程 描述符

匿名管道常常用来实现父子进程的通信。通过pipe函数创建两个文件描述符,分别指向管道的读端和写端。

从内核对于共享文件的实现来理解管道

  • 描述符表。每个进程都有它独立的描述符表,它的表项是由进程打开的文件描述符来索引的。每个打开的描述符表项指向文件表中的一个表项。
  • 文件表。所有的进程共享这张表。每个文件表的表项组成(针对我们的目的)包括当前的文件位置、引用计数(即当前指向该表项的描述符表项数), 以及一个指向 v-node 表中对应表项的指针。关闭一个描述符会减少相应的文件表表项中的引用计数。直到它的引用计数为零,内核删除这个文件表表项。
  • v-node表。所有的进程共享这张表。每个表项包含 stat 结构中的大多数信息,包括 st_mode 和 st_size 成员

多个文件描述符可以通过不同的文件表表项引用同一个文件,比如对同一个文件open了多次就会产生以下结果
imag

父子进程对于文件共享的实现就是fork后,父子进程具有相同的文件描述符表,因而共享相同的文件位置。只有父子进程都关闭了相应文件描述符,内核才会删除对应的文件表表项。
image

因此管道用于父子进程通信的情形就像下面这张图(管道由父进程创建,使用循环队列)
image

管道的读写特点(默认采用阻塞)

  • 写端全部关闭时(引用计数为0),读取完管道剩余数据后,再次read会返回0。
  • 写端未全部关闭(引用计数大于0),但管道中已经没有剩余数据时,再次read会阻塞,直到有数据可读。
  • 读端全部关闭时(引用计数为0),写数据会收到SIGPIPE信号,默认会导致进程异常终止。
  • 读端未全部关闭(引用计数大于0),管道写满后,再次write会阻塞,直到管道由剩余空间。

单个管道不用于双向通信,一个管道只用于单向的字节流原因:
如果一个进程可以对管道进行读写,可能会导致写入的字节又被自己读出,这显然是违背意图的。

在使用管道时,写进程关闭读端,读进程关闭写端的原因:

  • 减少管道占用资源
  • 如果读进程没有关闭写的文件描述符,那么即使写进程已经关闭了写入的描述符,由于仍有一个写入的描述符开着,读进程执行read的时候会保持阻塞。如果写进程没有关闭读的文件描述符,那么即使读进程已经已经关闭了读的描述符,写进程仍然能够往管道里写入,导致写满管道然后阻塞。正常情况,也就是当没有读的文件描述符存在时,写入管道操作会让当前进程收到SIGPIPE信号。

那该怎么实现双向通信?
使用两个匿名管道,分别用于单向的字节流。

标签:文件,表项,管道,匿名,关闭,进程,描述符
From: https://www.cnblogs.com/wangerblog/p/17795684.html

相关文章

  • python题目:使用lambda来创建匿名函数
    实例#!/usr/bin/python#-*-coding:UTF-8-*-MAXIMUM=lambdax,y:(x>y)*x+(x<y)*yMINIMUM=lambdax,y:(x>y)*y+(x<y)*xif__name__=='__main__':a=10b=20print('Thelargaroneis%d'%MA......
  • 5_nest管道和数据校验
    管道Nest在路由处理器之前调用管道,然后管道接收发往路由处理器的参数验证输入数据,给输入数据添加字段管道有两个典型的用例:验证:评估输入数据,如果有效,则将其原样传递;否则,当数据不正确时抛出一个异常。转型:把输入数据转换为所需的格式(例如,从字符串到整型)。设置全局Valida......
  • 17.2 实现无管道正向CMD
    WSASocket无管道正向CMD,使用WSASocket函数创建一个TCP套接字,并绑定到一个本地地址和端口上。然后使用CreateProcess函数创建一个新的CMD进程,并将标准输入、输出和错误输出重定向到套接字的句柄上。这样,客户端可以通过网络连接到这个套接字,发送CMD命令并获取命令输出结果。这种方......
  • 17.3 实现无管道反向CMD
    WSASocket无管道反向CMD,与无管道正向CMD相反,这种方式是在远程主机上创建一个TCP套接字,并绑定到一个本地地址和端口上。然后在本地主机上,使用WSASocket函数连接到远程主机的套接字,并将标准输入、输出和错误输出重定向到套接字的句柄上。这样,本地主机就可以通过网络连接到远程主机的......
  • redis其他操作、redis管道、django中使用redis、django缓存、celery介绍、补充单例
    redis其他操作'''delete(*names)exists(name)keys(pattern='*')expire(name,time)rename(src,dst)move(name,db))randomkey()type(name)'''#redis的key值,最大可以是多少?最大不超过512M一般1KB#redis的value值,最大可以是多少?最大不超过512M......
  • Linux-管道、环境变量、常用命令
    目录管道概念要点与文件重定向的区别环境变量概念查看常用命令查看系统状况权限文件查找用户相关工具管道概念管道的作用类似于文件重定向,可以将前一个命令的stout做为下一个命令的stdin要点管道命令进处理stdout,会忽略stderr管道右边的命令必须能接受stdin多个管道命令可......
  • Java拾贝第六天——匿名内部类
    Java拾贝不建议作为0基础学习,都是本人想到什么写什么匿名内部类匿名对象没忘吧?newPerson();//语法同匿名内部类匿名内部类就是匿名的局部内部类,地位同局部变量。有两种形式:基于接口的匿名内部类,基于类的匿名内部类基于接口的匿名内部类常规方式实现接口并重写其方法publ......
  • redis管道
    redis管道1.事务四大特性:-原子性:要么都成功,要么都失败-一致性:数据前后要一致-隔离性:多个事务之间互不影响-持久性:事务一旦完成,数据永久改变2.关系型数据库,支持事务3.redis有没有事务?没有专门的事情,但是通过标的方式可以实现事务的几个特性,所以我们......
  • PHP 核心特性之匿名函数
    来源:http://www.shanhubei.com/archives/2814.html在匿名函数出现之前,所有的函数都需要先命名才能使用functionincrement($value){return$value+1;}array_map('increment',[1,2,3]);有的时候函数可能只需要使用一次,这时候使用匿名函数会使得代码更加简洁直观,......
  • php匿名函数怎么写
    来源:http://www.shanhubei.com/archives/2808.htmlPHP匿名函数和闭包使用的句法与普通函数相同,但匿名函和闭包数其实是伪装成函数的对象.匿名函数:就是没有名称的函数.匿名函数可以赋值给变量,对象传递.不过匿名函数仍是函数,因此可以调用,还可以传入参数.匿名函数特别适合作......