管道一般是单向的。一个进程往里面写,另一个进程从里面读。下面是一个代码示例
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
int main()
{
pid_t pid;
int fd[2];
int n;
char buf[20]; //char* 也可以
if(pipe(fd) < 0)
{
perror("pipe error");
exit(1);
}
pid = fork();
if(pid < 0)
{
perror("fork error");
exit(1);
}
else if(pid > 0) //父进程
{
close(fd[0]); //关闭读功能
write(fd[1], "hello pipe\n", 19);
wait(NULL); //等待任意一个子进程终止
}
else // 0, 子进程
{
close(fd[1]);
sleep(1);
n = read(fd[0], buf, 20);
write(1, buf, n);//第一个入参为1,表示标准输出
}
return 0;
}
程序输出是:
zhanghaodeMacBook-Pro:cpp_excise zhanghao$ g++ 无名管道.cpp
zhanghaodeMacBook-Pro:cpp_excise zhanghao$ ./a.out
hello pipe
假设管道都是阻塞I/O操作,没有设置O_NONBLOCK标志。则:
- 如果所有写端的文件描述符都关闭了,单仍然在读,则剩余数据被读完了后,再次read会返回0。就像读到文件末尾一样。
- 如果写端没关闭,但也没写数据进去,那读端在读完管道所有字符后,会阻塞,直到管道有数据了才会继续下去。
- 如果所有读端都关闭了,写端再往里write,那么该进程会收到信号:SIGPIPE,可能会导致进程异常终止。
- 如果读端没关闭,但是也没读,那写端一直写会导致管道写满,就会阻塞,直到管道有空位置了才能继续写。(可能是64k,即65535)