特殊文件——管道

管道与重定向


概述

对于一些须要进程间的协做来解决问题的场景,进程间的通讯是必要的。而最简单的UNIX进程通讯机制就是管道,他是由特殊文件表示的。调用者能够经过文件描述符fd[0]和fd[1]来访问它,从fd[1]写入的数据能够按照先进先出的顺序从fd[0]中读出。html

文件描述符:在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者建立一个新文件时,内核向进程返回一个文件描述符。在程序设计中,一些涉及底层的程序编写每每会围绕着文件描述符展开。可是文件描述符这一律念每每只适用于UNIX、Linux这样的操做系统。shell

咱们要明白,每一个Unix进程(除了可能的守护进程)应均有三个标准的POSIX文件描述符,对应于三个标准流:vim

整数值 名称 <unistd.h>符号常量 <stdio.h>文件流
0 Standard input STDIN_FILENO stdin
1 Standard output STDOUT_FILENO stdout
2 Standard error STDERR_FILENO stderr

例如:$ls -l | head -5中,|就表示一个管道,ls的标准输出被经过中间通讯缓冲区被“链接”到了head的标准输入中。 此命令执行过程的文件描述符表的状态函数

实现重定向

了解了文件描述符的概念后,咱们就能利用dup2函数来实现重定向。下面咱们来用c语言模拟$ls -l | head -5spa

源代码

#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main(int argc, char *argv[])
{
    pid_t child;
    int fd[2];

    if ((pipe(fd) == -1) || ((child = fork()) == -1)) {
        perror("Failed to fork.");
        return 1;
    }

    if (child == 0) {     /* 子进程 */ 
        if (dup2(fd[1], STDOUT_FILENO) == -1)
            perror("Failed to redirect stdout of ls");
        else if ((close(fd[0]) == -1) || (close(fd[1]) == -1))
            perror("Failed to close extra pipe descriptors on ls");
        else {
            execl("/bin/ls", "ls", "-l", NULL);
            perror("Failed to execute ls");
        }
    }

    /* 父进程 */ 
    if (dup2(fd[0], STDIN_FILENO) == -1)
        perror("Failed to redirect stdin of head");
    else if ((close(fd[0]) == -1) || (close(fd[1]) == -1))
        perror("Failed to close extra pipe descriptors on head");
    else {
        execl("/usr/bin/head", "head", "-5", NULL);
        perror("Failed to execute head");
    }
    return 0;
}

过程图示

fork函数在建立一个子进程时,子进程就会继承父进程的环境和上下文中的大部份内容的一份拷贝,包括信号状态调度参数文件描述符表。因为子进程在被建立时会收到父进程文件描述符表的一份拷贝,所以对于在建立子进程前就打开的文件来书,父进程和子进程将共享同一个文件的偏移量。 调用fork后,文件描述符表状态以下: 调用后的文件描述符表状态操作系统

两个dup2函数执行完毕后,文件描述符表的状态以下: 两个函数执行完毕后的文件描述符表状态设计

调用close完毕后,文件描述符表的状态以下: 两个函数执行完毕后的文件描述符表状态3d

编译运行

$ gcc redirect_demo.c
$ ./a.out
total 4888
-rwxrwxr-x  1 chris chris    8576 3月   5 21:23 a.out
drwxrwx--- 10 chris chris    4096 3月   5 21:23 ccls
-rw-rw-r--  1 chris chris     637 3月   5 21:23 coc-25627.vim
-rw-rw-r--  1 chris chris   25829 3月   5 15:06 coc-ultisnips-c7dd5acb3d1574c377e86b60ee637c3c.py

原文出处:https://www.cnblogs.com/chrisynl/p/12422837.htmlcode

相关文章
相关标签/搜索