1. Pipe 的 Limitations(1)、半双工,一些系统已经提供全双工
(2)、只能用于具有共同祖先的2个进程之间,一般用于子进程和父进程之间
注:FIFO有第二个限制;Unix domain socket(UDS)和STREAMS-based pipes也有这2个限制
2. Pipe函数原型
#include <unistd.h> int pipe(int filedes[2]); 0 if ok, -1 on error
|
注:filedes[0]用来读,filedes[1]用来写
1是0的输入
3. 错误处理
(1) 如果PIPE的写端关闭,那么read PIPE会返回0来标明EOF
(2) 如果PIPE的读端关闭,那么write PIPE会返回-1并把errno设置为SIGPIPE
注:PIPE_BUF表示内核PIPE缓冲大小,大于它的数据会被切分,可以用pathconf和fpathconf来设置这个值
4. 典型代码
if (pipe(fd) < 0)
err_sys("pipe error");
if ((pid = fork()) < 0) {
err_sys("fork error");
} else if (pid > 0) {
close(fd[0]);
write(fd[1], "hello world\n", 12);
} else {
close(fd[1]);
n = read(fd[0], line, MAXLINE);
write(STDOUT_FILENO, line, n);
}
|
注:dup2(fd1, fd2); //用fd2值代替fd1 如果fd2已经打开,首先关闭;如果fd1==fd2,那么dup2返回fd2而不关闭fd2.
所以在使用dup2的时候最好先检查下fd1是否与fd2相等
5. popen和pclose
#include <stdio.h>
FILE *popen(const char *cmdsting, const char *type);
file pointer if OK, NULL on error
int pclose(FILE *fp);
termination status of cmdstring, or -1 on error
|
creat a pipe--> fork a child-->close unused ends of the pipe-->execute a shell to run command-->wait command terminate
cmdstring由bsh执行,也就是说,下面的字串都支持:
“ls *.c"或 "cmd 2>&1"
注:popen最后调用execl,所以不能被set-user-ID或者set-group-ID的程序调用,因为它继承调用者的权限
6. coprocesses
一般coprocess运行与backgound,而它的stdin和stdout都用pipe连接到另外一个程序,全双工pipe
注:KSH支持,BSH, BASH, CSH都不支持
7. FIFO(named pipes)
注1:FIFO无PIPE同一个祖先的限制,不相关的进程也能交换数据
注2:FIFO是一种文件,open(),close(),read(),write(), unlink(),etc函数都适用
(1)函数原型
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
0 if OK, -1 on error
|
mode与open()函数的mode一样(2)用处:
. 不创建临时中间文件,SHELL命令可以从1个SHELL管道传递数据到另外一个SHELL管道
. 用于C/S程序中服务器和客户端之间传递数据
(3)FIFO复制输出
mkfifo fifo1
prog3 < fifo1
prog1 < infile | tee fifo1 | prog2
|
(4)C/S模型FIFO
注1:well-known意思是FIFO的pathname被所有连接到server的client知道
注2:client-specific基于client的进程ID
阅读(647) | 评论(0) | 转发(0) |