无名管道
管道是linux中重要的通信方式,这里所说的是无名管道,无名管道具有以下特点:
- 他只能用于具有亲缘关系的进程之间(也就是父子进程或者是兄弟进程之间)
- 是一种半双工的通信模式,具有固定的读端pipefd[0]和写端pipefd[1]
- 可以把管道看成是一种普通的文件,对他的读写可以使用普通的read()和write()函数,但是又不是普通的文件,不属于其他任何文件系统,并且只存在于内核的内存空间中
管道是基于文件描述符的通信方式,当一个管道建立时,他会创建两个文件描述符pipefd[0], pipefd[1],其中pipefd[0]用于读管道,pipefd[1]用于写管道。当一个进程读管道时,它会以阻塞的方式等待另一个进程写管道,反之亦然。关闭管道只需调用close()逐个关闭各个文件描述符即可。
创建无名管道
NAME
pipe - create pipe
SYNOPSIS
#include <unistd.h>
int pipe(int pipefd[2]);
pipefd[0]是读端,用来读管道,pipefd[1]是写端,用来写管道
通常是先创建一个管道,再通过fork()函数创建一个子进程,该子进程会继承父进程所创建的管道
注意:
1)不要使用pipefd[0]来写数据,也不要使用pipefd[1]来读取数据,否则其行为是未定义的。
2)在用pipefd[0]来读数据时,要先关闭pipefd[1];在用pipefd[1]来写入数据时,要关闭pipefd[0]
代码演示
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#define debug(msg) { \
perror(msg); \
exit(1); \
}
int main()
{
int fd[2];
pid_t pid;
char buf[64];
if(pipe(fd) == -1)
debug("pipe");
if((pid = fork()) == -1)
debug("fork");
if(pid == 0)
{
//write
close(fd[0]);
write(fd[1], "hello world!\n", sizeof("hello world!\n"));
sleep(1);
close(fd[1]);
}else
{
//read
close(fd[1]);
read(fd[0], buf, 64);
printf("this is paren's message : %s", buf);
close(fd[0]);
}
return 0;
}