【问题标题】:how to send the pipe from parent to child process如何将管道从父进程发送到子进程
【发布时间】:2015-04-14 03:48:39
【问题描述】:

我正在尝试使用 fork 创建三个子进程,其中两个将 char 字符串写入管道,第三个将从 pipr 读取它并将其输出到屏幕上。我们应该创建 4 个文件并调用 exec 系统调用来访问这些文件。但我不知道如何将管道发送到其他进程。由于我尝试在主进程中创建 fd[2] 和 pipe(fd) 在子进程调用 close(fd[0]) 中,但它给了我未声明?我怎么能这样做。 这是我的代码

   int main(void){
int fd[2],z,status,i;
pid_t childB, childC, childD;
char *arg[1] = {0};
z = pipe(fd);
if(z <0 ){perror("create pipe"); exit(0);}

childB = fork();
if(childB==0){execv("PipeW1",arg);}
if(childB<0){printf("fork failed\n");exit(0);}
....

在 PipeW1 方法中,我这样做了:

    void main (int argc, char *argv[]){
    int i;
    char str[6];
    close(fd[0]);   
    for(i=1;i<=500;i++){
    sprintf(str,"%03daaa",i);
    z = write(fd[1],str,6);
    if(z<0) {perror("write process B"); exit(1);}
    if(i%100==0){usleep(100000);}
}
close(fd[1]);
exit(0);
}

任何建议都会有所帮助!

谢谢

【问题讨论】:

    标签: c pipe


    【解决方案1】:

    管道通过 execve 保持打开状态 - 但您不能在另一个程序中使用在一个程序中声明的变量 (fd[]),它不仅在不同的 C 范围内(编译单元),而且是完全不同的 /process image/ .

    但是,数值将保留 - 这就是管道的标识。因此,将代表管道“读取”端的数字 fd[0] 传递给子进程。通常使用 fork() 是很自然的,但由于您使用 exec(),因此最好的方法是在 argv[] 数组中将数字 fd[0] 作为命令行 arg 传递。请注意,这将是一个字符串,因此您需要使用类似 snprintf() 的东西来创建参数。

    【讨论】:

    • 那么如何将 fd[0] 作为参数传递?仍然不太确定。 @BadZen
    【解决方案2】:

    解决问题的一种方法是在子进程中重定向stdout。这可以通过dup2 完成。在fork 之后,子进程可以调用dup2stdout 连接到管道的写入端。然后可以关闭管道的文件描述符。在exec 之后,子进程通过写入stdout 来写入管道,例如printf

    这里有一个完整的例子来展示这些概念。

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    int main( void )
    {
        int fd[2];
        pid_t pid;
    
        if ( pipe( fd ) < 0 )
        {
            perror( "pipe" );
            exit( 1 );
        }
    
        if ( (pid = fork()) < 0 )
        {
            perror( "fork" );
            exit( 1 );
        }
    
        if ( pid == 0 )
        {
            dup2( fd[1], STDOUT_FILENO );   // attach the write end of the pipe to stdout
            close( fd[0] );                 // close the pipe (read end)
            close( fd[1] );                 // close the pipe (write end)
    
            char *args[] = { "./test", "hello", "world", NULL };
            execv( args[0], args );
        }
    
        // the following code is only for the parent, since the child has exec'd
        close( fd[1] );         // close the write end of the pipe
        char buffer[100];
        ssize_t length = read( fd[0], buffer, sizeof(buffer) - 1 );     // read from the child
        if ( length < 0 )
        {
            perror( "read" );
            exit( 1 );
        }
        buffer[length] = '\0';
        printf( "parent: %s", buffer );
        close( fd[0] );
    }
    

    test.c

    #include <stdio.h>
    #include <stdlib.h>
    
    int main( int argc, char *argv[] )
    {
        if ( argc < 2 )
        {
            printf( "no args\n" );
            exit( 1 );
        }
    
        for ( int i = 1; i < argc; i++ )
            printf( "%s%s", argv[i], (i+1 < argc) ? ", " : "\n" );
    }
    

    预期的输出是

    家长:你好,世界

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-16
      • 1970-01-01
      相关资源
      最近更新 更多