进程间通信(PIPE调用)

来源:互联网 发布:软件著作权办理时间 编辑:程序博客网 时间:2024/05/19 12:40

看过了高级的popen调用之后,我们来了解一下底层的pipe函数。popen函数用过启动一个shell来解释请求的命令。而pipe不需要启动shell来解释。

#include<unistd.h>int pipe(int file_descriptor[2]);

pipe函数的参数是一个由两个整数类型的文件描述符组成的数据的指针。该函数是数据中填上两个新的文件描述符后返回0.如果失败则返回-1并设置

errno来表明失败的原因。这些错误有

1.EMFILE:进程使用的文件描述符过多

2.ENFILE:系统的文件表已满

3.EFAULT:文件描述符无效

两个返回的文件描述符以一种特殊的方式连接起来。写到file_descriptor[1]的所有数据都可以从file_descriptor[0]读回来。数据基于先进先出的原则

(通常简写为FIFO)进程处理,这意味着如果你把字节1,2,3写入到dile_descriptor[1],从file_descriptor[0]读出来的数据是1,2,3.

#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>int main(){    int data_processed;    int file_pipes[2];    const char some_data[] = "123";    char buffer[BUFSIZ + 1];    memset(buffer, '\0', sizeof(buffer));    if (pipe(file_pipes) == 0) {        data_processed = write(file_pipes[1], some_data, strlen(some_data));        printf("Wrote %d bytes\n", data_processed);        data_processed = read(file_pipes[0], buffer, BUFSIZ);        printf("Read %d bytes: %s\n", data_processed, buffer);        exit(EXIT_SUCCESS);    }    exit(EXIT_FAILURE);}

跨越fork调用的管道

#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>int main(){    int data_processed;    int file_pipes[2];    const char some_data[] = "123";    char buffer[BUFSIZ + 1];    pid_t fork_result;    memset(buffer, '\0', sizeof(buffer));    if (pipe(file_pipes) == 0) {        fork_result = fork();        if (fork_result == -1) {            fprintf(stderr, "Fork failure");            exit(EXIT_FAILURE);        }// We've made sure the fork worked, so if fork_result equals zero, we're in the child process.        if (fork_result == 0) {            data_processed = read(file_pipes[0], buffer, BUFSIZ);            printf("Read %d bytes: %s\n", data_processed, buffer);            exit(EXIT_SUCCESS);        }// Otherwise, we must be the parent process.        else {            data_processed = write(file_pipes[1], some_data,                                   strlen(some_data));            printf("Wrote %d bytes\n", data_processed);        }    }    exit(EXIT_SUCCESS);}
父进程与子进程

#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>int main(){    int data_processed;    int file_pipes[2];    const char some_data[] = "123";    char buffer[BUFSIZ + 1];    pid_t fork_result;    memset(buffer, '\0', sizeof(buffer));    if (pipe(file_pipes) == 0) {        fork_result = fork();        if (fork_result == (pid_t)-1) {            fprintf(stderr, "Fork failure");            exit(EXIT_FAILURE);        }        if (fork_result == 0) {            sprintf(buffer, "%d", file_pipes[0]);            (void)execl("pipe4", "pipe4", buffer, (char *)0);            exit(EXIT_FAILURE);        }        else {            data_processed = write(file_pipes[1], some_data,                                   strlen(some_data));            printf("%d - wrote %d bytes\n", getpid(), data_processed);        }    }    exit(EXIT_SUCCESS);}

// The 'consumer' program, pipe4.c, that reads the data is much simpler.//pipe4.c#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>int main(int argc, char *argv[]){    int data_processed;    char buffer[BUFSIZ + 1];    int file_descriptor;    memset(buffer, '\0', sizeof(buffer));    sscanf(argv[1], "%d", &file_descriptor);    data_processed = read(file_descriptor, buffer, BUFSIZ);    printf("%d - read %d bytes: %s\n", getpid(), data_processed, buffer);    exit(EXIT_SUCCESS);}

原创粉丝点击