一、无名管道
1.1无名管道概述
无名管道虽然是在内核空间创建的,但是会给当前用户进程两个文件描述符,一个负责执行读操作,一个负责写操作。
管道是最古老的UNIX IPC方式,其特点是:
1、半双工,数据在同一时刻只能在一个方向上流动。
2、写入管道中的数据遵循先入先出的规则。
3、管道所传送的数据是无格式的,这要求管道的读写方式必须事先约定好数据的格式,比如说多少个字节算一个消息等。
4、管道不是普通的文件,不属于某个文件系统,其中只存在于内存中。
5、数据只能一端进一端出。
6、管道在内存中对应的一个缓冲区,不同的系统其大小不一定相同。
7、从管道读取数据是一次性操作,数据一点别读走,他就从管道中被抛弃,释放空间以便写更多的数据。
8、管道没有名字,只能存在具有公共祖先的进程之间使用
1.2无名管道的创建 -- pipe函数
案例:
结果:
1.3无名管道实现进程件的通信
案例:
结果:
注意:
利用无名管道实现进程的通信,都是父进程创建无名管道,然后再创建子进程,子进程继承父进程的文件描述符,然后父子进程通过读写无名管道实现通信。
1.4通过fcntl函数设置文件的阻塞特性
设置为阻塞:
fcntl(fd, F_SETFL, 0);
设置为非阻塞:
fcntl(fd, F_SETFL, O_NONBLOCK);
二、文件描述符概述
文件描述符是非负数的,是文件的标识。
用户使用文件描述符(file descriptor)来访问文件。
每个进程间都有一张文件描述符的表,进程刚刚被创建时,标准输入、标准输出、标准错误输出。
设备文件被打开,对应的文件描述符0、1、2记录在表中。
在进程中打开其文件时,系统会返回文件描述符表中最小可用的文件描述符,并将此文件描述符记录在表中。
三、文件描述符的复制
3.1dup函数
3.1.1案例1:使用dup函数赋值文件描述符
执行结果:
3.1.2案例2:实现输出重定向的功能
执行结果:
3.13案例3:实现输出重定向后,又想标准输出,如何实现
执行结果:
四、有名管道
4.1有名管道的概述
命名管道(FIFO)和管道(pipe)基本相同,但有一些明显的不一样。
它的特点是:
1、半双工,数据在同一时刻只能在一个方向上流动。
2、写入FIFO中的数据遵循先入先出的规则。
3、FIFO所传送的数据是无格式的,这要求FIFO的读出方式与写入方式必须实现商量好格式。
4、FIFO在文件系统中作为一个特殊的文件而存在并且在文件系统中可见,所以有名管道可以实现不相关进程间的通信,但FIFO中的内容却放在内存中。
5、管道在内存中存在对应一个缓冲区。不同的系统其大小不一定相同。
6、从FIFO读数据是一次性操作,数据一旦被读他就从FIFO中被抛弃,释放空间以便写更多的数据。
7、当时用FIFO的进程退出后,FIFO文件将继续保存文件在系统中以便以后使用
8、FIFO有名字,不相关的进程可以通过打开命名管道进行通信
4.2有名管道的创建
方法一:用shell命令mkfifo创建有名管道:
方法二:使用函数mkfifo
结果:
4.3有名管道的基本读写
由于有名管道在本地创建了一个管道文件,所以系统调用的IO函数基本都可以对有名管道进行操作,但是不能使用lseek修改管道文件的偏移量。
注意:有名管道创建的本地的文件知识起到标识作用,真正的有名管道实现进程间的通信还是在内核空间开辟内存,所以本地产生的文件知识一个标识,没有其他的作用,对本地管道文件的操作实质就是对内核空间的操作。
4.4有名管道实现进程间通信
由于有命管道在本地创建了一个管道文件,所以不想干的进程间也可以实现通信
4.4.1send
4.4.2recv
执行结果: