Linux基础:有名管道和无名管道

一.进程间通信:

管道 信号量 共享内存 消息队列 套接字

二.有名管道:

有名管道(可以在任意两个进程之间通信)
无名管道(只能在父子进程之间进行通信)
(有一个读端和一个写端,缺一不可)

  1. 管道写端关闭,则读端返回值为0;
  2. 管道读端关闭,则写端会产生异常(会收到信号SIGPIPE)
  3. 管道为空, 那么读会阻塞
  4. 管道写满, 那么写会阻塞
    面试常问:
    1.有名管道和无名管道的区别:有名管道可以在任意两个进程之间通信;
    无名管道只能在父子进程之间进行通信
    2.写入管道的数据在哪里? 在内存中(不是在磁盘上)
    3.管道的通信方式: 半双工(数据可以从a到b,也可以从b到a,但是某一时刻只能选择其中一个)
    代码示例:a和b是两个独立的程序,a从键盘上获取hello,然后想交给程序b,让b程序打印出来,则可以创建一个文件(管道文件),将a进程中键入的hello写入新创建的文件中,然后再让b进程从文件中读取。a和b的代码如下:

    可以发现在同一个窗口中执行b进程读取数据时,阻塞了,关闭b进程,执行a时,也会阻塞,即代码中的open没有返回。而当打开两个窗口分别执行a进程和b进程时,会成功。
    运行结果如下:

    接下来,对a中的代码进行修改,在键盘上输入数据,并写入新建的管道文件中,再让b来读取。

    运行结果为:
    管道读端关闭,则写端会怎么样呢?下面来看一段代码并进行演示:


    运行结果如下:

    若在a进程中,输入end,则a程序和b程序会自动退出。但先结束b进程的读取,在a程序中输入任何字符,a程序则会退出。说明了当b程序结束退出,则a程序会随之收到一个信号,再跟着退出(接收端都已经关闭了,则没必要再往里面写数据),下面我们将这个信号加入代码中,进行演示:

    运行结果如下:
    在
    从上面的进程可以看出,当先结束b进程时,a进程中会收到13号信号,来提示读数据的进程结束,但并不会结束a进程。则可以键入end退出a进程。

三.无名管道

在一个进程中,创建一个管道,在管道中fd[0]默认为读,fd[1]默认为写。再用fork产生一个子进程,子进程随之会复制父进程打开的文件,则子进程中也会有fd[0]默认为读,fd[1]默认为写。因此,该管道可以被子进程写数据以及读取数据。即父子进程之间可以进行交互读写数据。(在最开始关闭父进程的读和子进程的写,只需用父进程进行写入数据,再在子进程中读数据)
在管道中进行读写,并打印:
在最开始关闭父进程的读和子进程的写,只需用父进程进行写入数据,再在子进程中读数据,代码如下:
运行结果:

**注:**管道是在内核中为其分配内存空间进而创建,不在堆中也不在栈上。
管道的实现(如图):一个空间,两个指针,一读一写进行操作。(不断读不断写,空间循环利用)

头指针进行写数据,尾指针读数据。(写入100个数据,10次可以读完。读和写并没有严格的规定)

  • 11
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值