《UNIX环境高级编程》笔记--无名管道

1.pipe

管道是UNIX系统IPC的最古老形式,并且所有的UNIX系统都提供此种通信机制。管道有下列两种局限性:

a.历史上,它们是半双工的,现在某些系统提供全双工管道,但是为了最佳的可移植性,我们决不应预先假定系统使用此

特性。

b.它们只能在具有公共祖先的进程之间使用。通常一个管道由一个进程创建,然后该进程调用fork,此后父子进程之间可以

使用该管道。

(FIFO没有第二种局限性,UNIX域套接字和命名流没有这两种局限性)

管道是由调用pipe函数而创建的:

#include<unistd.h>
int pipe(int filedes[2]);
//成功则返回0,出错则返回-1.
经由参数filedes返回两个文件描述符:filedes[0]为读而打开,filedes[1]为写而打开。filedes[1]的输出是filedes[0]的输入。

《UNIX环境高级编程》笔记--无名管道

调用fork之后做什么取决于我们想要有的数据流的方向,对于从父进程到子进程的管道,父进程关闭管道的读端fd[0],子

进程则关闭写端fd[1]。

调用fork之后的半双工管道:

《UNIX环境高级编程》笔记--无名管道

从父进程到子进程的管道:

《UNIX环境高级编程》笔记--无名管道

为了构造从子进程到父进程的管道,父进程关闭fd[1],子进程关闭fd[0]。

当管道的一端被关闭后,下列两条规则其作用:

a.当读一个写端已经被关闭的管道时,在所有数据都被读取后,read返回0,指示达到了文件结束处。

b.如果写一个读端已经被关闭的管道,则产生信号SIGPIPE。如果忽略该信号或者捕获该信号并从其处理程序返回,则

write返回-1,errno设置为EPIPE。

在写管道是,常量PIPE_BUF规定了内核中管道缓冲区的大小,如果对管道调用write,而且要求写的字节数小于等于

PIPE_BUF,则此操作不会与其他进程对同一管道的write操作穿插进行。但是,若有多个进程同时写一个管道,而且

进程要求写的字节数超过PIPE_BUF字节数时,写操作的数据可能穿插。


实践:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>

int main(void){
        int result,n;
        int fd[2];
        pid_t pid;
        char line[256];

        if(pipe(fd) < 0){
                perror("pipe");
                return -1;
        }

        if((pid = fork()) < 0){
                perror("fork");
                return -1;
        }else if(pid > 0){ //parent
                close(fd[0]);
                if(fd[1] != STDOUT_FILENO){
                        dup2(fd[1],STDOUT_FILENO);
                }
                execl("/bin/ls","ls",(char*)0);
        }else{ //child
                close(fd[1]);
                while((n =read(fd[0],line,256)) > 0){
                        if(write(STDOUT_FILENO,line,n) != n){
                                perror("write");
                                exit(-1);
                        }
                }
                close(fd[0]);
        }
        return 0;
}
运行结果:

WinVNC.log
a.out
a.txt
b.txt
chlock
dtest
lock
lock.txt

在父进程中将管道描述符赋值为标准输出,所以在执行ls后,原本是写到标准输出的,现在写到fd[1]中。而子进程将读到

的内容显示到标准输出上。

2.popen和pclose函数

常见的操作时






















《UNIX环境高级编程》笔记--无名管道

上一篇:@autoreleasepool内存管理


下一篇:EBS Form开发中的Record Group(记录组)