linux 进程管道

进程访问机制,各个进程比较独立,不能访问对方的单元,但是进程不可能永远时对立的,必须涉及到信息的交互。

进程间通信传递两种信息,一种时标记、标志也就是状态(同步的状态信号量,异步的状态信号),另外一种是数据,即内容(传送的文件,磁盘、内存(有序的消息队列、共享内存,socket)、普通上锁文件、管道(有名管道、无名管道)、mmap。

管道的实现原理:

文件实现进程间的通信,普通文件可以同时被多个进程访问而无法相互感知,所以,不能使用普通文件来实现进程间通信(flock这个机制实际上是一个同步概念),因此出现了管道这个特殊的文件。由操作系统来维护的一段“内核内存空间”,类似与FIFO这种管道队列,因此称为管道。

(1)上层应用时,它就是文件,可以使用read/write/close等操作。

(2)它是特殊的文件,操作时不能进行lseek.

(3)管道是单向的。如果要实现双向,只能创建两个管道。

具体编程

(1)创建无名管道。pipe

int pipe(int pipefd[2]);

pipefd在调用者是一个数组,用来存放管道的两个返回文件描述符。

pipefd[0]用来读,pipefd[1]用来写。

(2)读写read/write函数。

read(fd[0],);

write(fd[1]);

(3)无名管道的限制

读写的限制

要进程读,就一定要有人写,要进行写,就一定有人要读。

(1)以阻塞方式读无名管道,如果当前没有一个进程(包括自己)与这个管道的写端关联,读操作立即返回。

如果有数据,且大于欲读出的数据量,读出试图读取的数据大小。

如果有数据,但是小于欲读出的数据量,读出所有管道数据。

如果没有数据,立即返回0.

(2)以阻塞方式读无名管道,有一个及以上进程(包括自己)与这个管道的写端关联,读操作做如下:

如果有数据,现有数据小于期望读取的值,读立即返回现有数据。

如果有数据,现有数据大于期望读取的值,读立即返回期望读写数据。

如果没有 数据,则阻塞,当有数据写入后,唤醒读操作。

(3)以阻塞方式写无名管道,如果有一个或者多个进程与这个管道的独端关联,如果当前管道已经满,则阻塞,当有进程读出数据,唤醒写操作。

(4)以阻塞方式写无名管道,如果没有进程与这个管道的读端关联,党有进程净产生SIFPIPE的信号,而这个信号的默认操作时种植当前进程,因此很多时候测试无效果,需要安装信号。

重定向及无名管道应用

<输入重定向,要求这个输入文件必须存在。

>输出重定向,如果文件不存在,创建,否则覆盖。

>>输出重定向,如果文件不存在,创建,否则追加。

2>

2>以上时对错误输出信息重定向到文件。

实现ps aux | grep test 或者 who | sort

(1)两个通信进程,ps aux 用execX函数来执行,grep init 是另一个进程,用execX来执行。为了方便,由一个父亲进程来创建这两个进程的通信。

(2)管道。这个管道要被两个进程都访问,父子进程。

(3)实现重定向。文件描述符复制。在ps aux中输出重定向,即将fd[1]复制为1,即以后写入到1中的数据全部写入到fd[1]中。默认情况下,一个进程的0,1,22三个文件描述符是默认打开的。因此,怎末来复制实现。

int dup(int oldfd);

复制oldfd为当前进程中最小未使用的文件描述符。

close(1);

dup(fd[1]);

如果0是默认打开的,dup函数返回1,以后写入到1的内容也就写入到fd[1]中。

int dup2(int oldfd,int newfd);

更方便是使用dup2,将oldfd复制为newfd,如果newfd关联打开的一个文件,则关闭这个文件。再复制。

dup2(fd[1],1)

能够保证fd[1]为后续输入出重定向的文件。

文件描述符的复制与新开文件是有本质区别的。复制文件描述时,两个文件描述共享文件表项,即共享读写文件。

新打开一个文件,其实时额外的申请文件表项,两者互不影响。

无名的管道,通信方向要了解创建的管道对应的文件描述符,因此,多用于父子进程或者亲缘关系之间,因为可以方便的实现文件描述符传递,

在重定向中还有流的重定向。popen/pclose.

 

 

 

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Linux父子进程管道通信是指在Linux操作系统中,父进程和子进程之间通过管道进行通信的过程。管道是一种特殊的文件,可以实现进程间的数据传输。在父进程中创建管道后,可以通过fork()系统调用创建子进程,并将管道的文件描述符传递给子进程。子进程可以通过管道读取父进程发送的数据,也可以向管道中写入数据,供父进程读取。这种通信方式可以实现进程间的数据共享和协作,是Linux操作系统中常用的进程间通信方式之一。 ### 回答2: 在Linux操作系统中,进程间通信是非常重要的一个功能。父子进程管道通信也是一种非常常用的进程间通信方式。 在Linux中,管道分为匿名管道和命名管道两种类型。匿名管道是由父进程创建,并将其写端的文件描述符传递给子进程。子进程就可以使用这个文件描述符来读取父进程写入管道的数据。而父进程也可以通过管道的另一端来读取子进程写入管道的数据。 在创建管道之前,我们需要使用系统调用pipe()来创建一个管道。具体的操作有两种方式,一种是用fcntl系统调用函数打开管道,另一种是用mkfifo函数创建命名管道。 在匿名管道中,父进程会在fork()函数之后,创建一个新的子进程。子进程会继承父进程的文件描述符,包括匿名管道的读端和写端。父进程在创建子进程后,将匿名管道的写端关闭,并使用管道的读端来从管道中读取数据。同时,子进程在继承父进程的文件描述符之后,也会关闭读端,并使用管道的写端来向管道中写入数据。 在命名管道中,父进程在创建命名管道后,可以打开命名管道的读端和写端,并使用这个文件描述符来读取和写入数据。而子进程只需要打开命名管道的读端或写端即可,以便向管道中写入或读取数据。 总之,父子进程管道通信是Linux操作系统中非常常见的一种进程间通信方式。通过匿名管道和命名管道,父进程和子进程可以方便地将数据传递给对方,从而实现进程间通信。 ### 回答3: Linux父子进程管道通信是指在一个进程中创建了另一个进程,它们之间通过管道通信来实现信息的传递。管道是一种特殊的文件类型,分为匿名管道和命名管道两种。在Linux系统中使用最广泛的是匿名管道,它只能在局部范围内进行数据传输。 借助管道机制,父进程可以向子进程传递数据,也可以从子进程读取数据。通常情况下,父进程负责向子进程传递命令,子进程负责接收并处理命令,然后将结果返回给父进程。 当父进程创建子进程后,它需要使用fork函数来完成进程复制。复制成功后,父进程和子进程就拥有了各自独立的内存空间和寄存器状态,它们之间的通信就需要通过特殊的IPC(Inter-Process Communication,进程间通信)机制来实现。 管道通信相对于其他的IPC方式来说比较简单,但是也存在一定的限制和缺陷。管道的数据传输是基于流的方式进行,因此无法识别消息之间的边界。同时,管道的传输速度依赖于缓冲区的大小和传输数据的大小,如果数据量过大可能会导致阻塞。 除了管道通信,Linux还提供了其他多种IPC方式,如消息队列、共享内存、信号量等,每种方式都有自己的优缺点和适用范围。在使用IPC机制时,需要根据实际需要选择最合适的方式来完成进程间的通信,以提高程序运行效率和可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值