无名管道
无名管道是Linux中进程间通信的一种方式。
• 它只能用于具有亲缘关系的进程之间的通信
(也就是父子进程或者兄弟进程之间)。
• 它是一个半双工的通信模式,具有固定的读端和写端。
• 管道也可以看成是一种特殊的文件,对于它的读写也可以使用普通的read()和write()等函数。但是它不是普通的文件,并不属于其他任何文件系统,即只存在于内核的内存空间中。
管道是基于文件描述符的通信方式,当一个管道建立时,它会创建两个文件描述符fds[0]和fds[1],其中
◇fd[0]固定用于读管道
◇fd[1]固定用于写管道
这样就构成了一个半双工的通道。
创建管道可以通过调用pipe()来实现。
管道关闭时只需使用普通的close()函数逐个关闭各个文件描述符。
构成了一个半双工的通道。
用pipe()函数创建的管道两端处于一个进程中,由于管道是主要用于在不同进程间通信的,因此这在实际应用中没有太大意义。实际上,通常先是创建一个管道,再通过fork()函数创建一子进程,该子进程会继承父进程所创建的管道 。
父子进程分别拥有自己的读写通道,为了实现父子进程之间的读写,只需把无关的读端或写端的文件描述符关闭即可。此时,父子进程之间就建立起了一条“子进程写入父进程读”的通道。
管 道无名管道读写注意点
当管道中无数据时,读操作会阻塞向管道中写入数据时,linux将不保证写入的原子性,管道缓冲区一有空闲区域,写进程就会试图向管道写入数据。如果读进程不读走管道缓冲区中的数据,那么写操作将会一直阻塞。
只有在管道的读端存在时,向管道中写入数据才有意义。否则,向管道中写入数据的进程将收到内核传来的SIFPIPE信号(通常Broken pipe错误)。
对一个关闭写端的管道做读操作时将返回0
下面是例子:
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
int main()
{
int fd[2];
pipe(fd);//创建无名管道
int re = fork();//创建子进程
char buffer[4];
memset(buffer,'\0',sizeof(buffer));//buffer初始化为'\0'
if(re == 0)
{
close(fd[0]);//子进程关闭读端口
write(fd[1],"abc",3);//向无名管道写内容
}
else if(re > 0 )
{
close(fd[1]);//父进程关闭写端口
read(fd[0],buffer,sizeof(buffer));//从无名管道读内容
printf("read from fd[0] and buffer is :%s\n",buffer);
}
close(fd[0]);
close(fd[1]);
return 0;
}