zoukankan      html  css  js  c++  java
  • 无名管道跟dup,dup的使用

    参考资料:

    http://www.tldp.org/LDP/lpg/node11.html

    http://blog.csdn.net/yeyuangen/article/details/6852682

    http://blog.sina.com.cn/s/blog_65c5c5990100mx6d.html

    管道是Linux中很重要的一种通信方式,是把一个程序的输出直接连接到另一个程序的输入,常说的管道多是指无名管道,无名管道只能用于具有亲缘关系的进程之间,这是它与有名管道的最大区别。

    下面是一个最简单的匿名管道的例子。

    子进程中,先关闭管道的读出端,然后在管道的写端写入数据

    在父进程中,先关闭管道的写入端,然后在管道的读出端读出数据。

    int pipe( int fd[2] ); 
    NOTES: fd[0] is set up for reading, fd[1] is set up for writing
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(void)
    {
        int     fd[2], nbytes;
        pid_t   childpid;
        char    string[] = "Hello, world!
    ";
        char    readbuffer[80];
    
        pipe(fd);
        
        if ((childpid = fork()) == -1)
        {
            perror("fork");
            exit(1);
        }
    
        if (childpid == 0)
        {
            /* Child process closes up input side of pipe */
            close( fd[0] );
    
            /* Send "string" through the output side of pipe */
            write(fd[1], string, (strlen(string)+1));
            exit(0);
        }
        else
        {
            /* Parent process closes up output side of pipe */
            close( fd[1] );
    
            /* Read in a string from the pipe */
            nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
            if (nbytes != -1)
            {
                printf("Received string: %s", readbuffer);
            }
                
        }
            
            return(0);
    }

     下面将dup跟管道结合其来使用。

    在子进程中调用  dup2(fd[1], STDOUT_FILENO); 则printf("hello world ");的数据就会写入到fd[1]中

    在父进程中调用 dup2(fd[0], STDIN_FILENO); 则fgets(readbuffer, sizeof(readbuffer), stdin);会把fd[0]的数据读取出来。

    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(void)
    {
        int     fd[2], nbytes;
        pid_t   childpid;
        char    string[] = "Hello, world!
    ";
        char    readbuffer[80];
    
        pipe(fd);
        
        if ((childpid = fork()) == -1)
        {
            perror("fork");
            exit(1);
        }
    
        if (childpid == 0)
        {
            /* Child process closes up input side of pipe */
            close( fd[0] );
    
            /* Send "string" through the output side of pipe */
            dup2(fd[1], STDOUT_FILENO);
            //write(fd[1], string, (strlen(string)+1));
            printf("hello world
    ");
            fflush(stdout);
            exit(0);
        }
        else
        {
            /* Parent process closes up output side of pipe */
            close( fd[1] );
    
            /* Read in a string from the pipe */
            dup2(fd[0], STDIN_FILENO);
            //nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
            fgets(readbuffer, sizeof(readbuffer), stdin);
            if (nbytes != -1)
            {
                printf("from the stdin,Received string: %s", readbuffer);
            }
                
        }
            
            return(0);
    }

    Often, the descriptors in the child are duplicated onto standard input or output. The child can then exec() another program, which inherits the standard streams. Let's look at the dup2() system call:

    我们的子进程把它的输出重定向的管道的写端,然后,父进程将它的输入重定向到管道的读端

    子进程关闭 管道读端  close( fd[0] );  调用  dup2(fd[1], STDOUT_FILENO);  将管道的写端重定向到标准输出

    父进程关闭 管道写端 close( fd[1] );   调用  dup2(fd[0], STDIN_FILENO);    将管道的读端重定向到标准输入

    The child can then exec() another program, which inherits the standard streams.

    工作流程:

    子进程调用  execlp( "ls", "ls", "-1", NULL );  ----> 标准输出----->管道的写端------->

    管道的读端(父进程)------->标准输入---->execlp( "wc", "wc", "-l", NULL );

    我们看到的结果是  ls -1|wc -l 的结果

    管道命令的使用  :

    第一条命令 | 第二条命令

    将第一条命令的结果作为第二条命令的参数来使用

    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(void)
    {
        int     fd[2], nbytes;
        pid_t   childpid;
        char    string[] = "Hello, world!
    ";
        char    readbuffer[80];
    
        pipe(fd);
        
        if ((childpid = fork()) == -1)
        {
            perror("fork");
            exit(1);
        }
    
        if (childpid == 0)
        {
            /* Child process closes up input side of pipe */
            close( fd[0] );
    
            /* Send "string" through the output side of pipe */
            dup2(fd[1], STDOUT_FILENO);
            execlp( "ls", "ls", "-1", NULL );
     
            exit(0);
        }
        else
        {
            /* Parent process closes up output side of pipe */
            close( fd[1] );
    
            /* Read in a string from the pipe */
            dup2(fd[0], STDIN_FILENO);
            execlp( "wc", "wc", "-l", NULL );
                
        }
            
        return(0);
    }
  • 相关阅读:
    解决Cannot change version of project facet Dynamic web module to 3.0
    mysql 存储过程
    查看建表语句
    mysql query cache 查询缓存
    数据库连接池
    JDBC Statement PrepareStatement
    mysql 改变表结构 alter
    maven 获取pom.xml的依赖---即仓库搜索服务
    windows常用快捷键
    oracle 的数据完整性
  • 原文地址:https://www.cnblogs.com/zhangxuan/p/6274107.html
Copyright © 2011-2022 走看看