【Linux】管道文件(有名管道、无名管道)

【Linux】管道文件(有名管道、无名管道)

多进程编程的目的就是为了同时完成多个任务。

例如:一个产品,一个软件,需要n个进程同时执行才能完成,而这些进程之间一定是有所联系的。

因此:多进程工作时,进程间需要通讯(传递数据)。

fork()创建的子进程,与父进程之间唯一共享的是文件描述符。

 

进程之间的通讯方式有:

  1. 管道
  2. 信号量
  3. 消息队列
  4. 共享内存
  5. Socket (用于网络通讯,即不同主机上进程之间的通讯)

【Linux】管道文件(有名管道、无名管道)_第1张图片

关于单工、半双工、全双工通讯

单工通讯:任意时刻,数据流向均为单向

半双工通讯:同一时刻,数据流向为单向(管道文件)

全双工通讯:任意时刻,数据流向双向,即有两条信道(A->B  B->A)

 

管道

①有名管道(命令管道)

在磁盘上会存储一个管道文件表示(inode存于内存上),但它并不会占据磁盘空间(block),数据并不会存储到磁盘上。

有名管道限制:同一台主机上,同一个系统有权限操作管道文件的任意进程都可以通过其完成进程间通讯。

【Linux】管道文件(有名管道、无名管道)_第2张图片

②无名管道

无名管道不存在管道文件,其借助于父子进程共享fork之前打开的文件描述符。(文件打开机制)其数据存储在内存中。

无名管道限制:只能使用于父子进程之间(无法跨越父子关系)

【Linux】管道文件(有名管道、无名管道)_第3张图片

管道的使用

①有名管道的使用

1、创建管道文件

命令:mkfifo 文件名

函数:int mkfifo(const char* pathname , int mode);

(其中 pathname为路径+文件名     mode为权限)

 

2、打开管道文件

int open();同文件操作中open的使用。

仅仅打开文件,如果不存在,则无法创建。

参数有两个:

参数一:打开管道文件的路径+名称

参数二:打开文件方式

注意!!!!在仅仅一端打开时,open会阻塞,只到有读端、有写端,open才会返回。

读和写的次数无必然联系。

 

3、写操作

int write();同文件操作中write的使用。

 

4、读操作

int read();同文件操作中read的使用。

 

注意:读写操作也会阻塞↓

read阻塞:管道中无数据。

返回条件:管道中有数据/所有的写端关闭

write阻塞:管道缓存区满。

返回条件:管道中有空间/所有的读端关闭

 

5、关闭

Int close();同文件操作中close的使用。

 

例题练习:A进程接收用户输入,B进程统计用户输入字节的个数。

代码展示:

maina.c

【Linux】管道文件(有名管道、无名管道)_第4张图片

mainb.c

【Linux】管道文件(有名管道、无名管道)_第5张图片

 

结果:

②无名管道的使用

创建并且打开无名管道(自带open过程)

int pipe(int fds[2]);

fds[2]初始时同时打开,fd[0]管道读端, fd[1]管道写端

Fork();//注意:一定要在fork之前打开pipe

 

父子进程均可读可写

如果父-->子进程,则父进程关闭读端,子进程关闭写端

如果子-->父进程,则子进程关闭读端,父进程关闭写端

 

读端判断是否通讯完成,read返回值:0

【Linux】管道文件(有名管道、无名管道)_第6张图片

例题练习:父进程接收用户输入,子进程统计字节并且输出。

代码:

【Linux】管道文件(有名管道、无名管道)_第7张图片

【Linux】管道文件(有名管道、无名管道)_第8张图片

结果:

你可能感兴趣的:(Linux)