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