【问题标题】:anonymous pipes in c with execlp带有execlp的c中的匿名管道
【发布时间】:2014-04-01 10:38:52
【问题描述】:

我的大学有一个作业,其中我必须有一个主进程和 3 个子进程。我必须从用户那里读取主进程中的一个表达式,然后通过 p1 进程的匿名管道将其传递给标准输入的重定向。然后我必须修改它并用另一个管道将它传递给 p2。然后 p3 与另一个管道发生同样的事情。最后,我必须使用另一个管道将最终表达式从 p3 返回到主进程。当我通过调用 fork 在主进程中创建 p1、p2、p3 进程时,我使用 execlp 运行每个进程的代码。

到目前为止,我设法做的(除了每个进程的逻辑非常复杂)是将用户的表达式从主进程发送到 p1 进程。在主进程p1的代码中,我将p1的输入重定向到第一个管道的读取端,我成功地从主进程读取了表达式。

我的问题在于其他进程。我真的陷入了如何正确重定向每个管道的输入和输出以与所有进程通信的问题。我真的很感激这里的任何帮助。 提前谢谢你。

【问题讨论】:

    标签: c redirect pipe


    【解决方案1】:

    在这个示例中,您可以看到 execlp() 函数和 fork() 函数:

    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    main()
    {
       pid_t pid;
       char *pathvar;
       char newpath[1000];
    
       pathvar = getenv("PATH");
       strcpy(newpath, pathvar);
       strcat(newpath, ":u/userid/bin");
       setenv("PATH", newpath);
    
       if ((pid = fork()) == -1)
          perror("fork error");
       else if (pid == 0) {
          execlp("newShell", "newShell", NULL);
          printf("Return not expected. Must be an execlp error.n");
       }
    }
    

    在这里你可以看到如何在两个进程之间建立管道:

    /*
     “ls -R | grep <pat>” where <pat> is a pattern
     */
    
    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    
    int main(int argc, char *argv [])
    {
        int pipe1[2];
        int pid1;
        int pid2;
        char stringa[100];
    
        pipe(pipe1); // creo la pipe
    
        if((pid1=fork())==0)
        {
            close(pipe1[0]);
            dup2(pipe1[1],1);
            close(pipe1[1]);
            execlp("ls","ls","-R",NULL);
        }
    
        if((pid2=fork())==0)
        {
            close(pipe1[1]);
            dup2(pipe1[0],0);
            close(pipe1[0]);
            execlp("grep","grep",argv[1],NULL); 
        }
    
        close(pipe1[0]);
        close(pipe1[1]);
        waitpid(pid1,NULL,0);
        waitpid(pid2,NULL,0);
        exit(0);
    
    }
    

    【讨论】:

    • 感谢您的回答。第二个例子更接近我的需要。这是我的问题。为什么在第二个过程中您不关闭 fd 的读取端?又为什么要关闭父进程中管道的读写呢?
    • 匿名管道是连接两个具有共同祖先的进程的通信通道。每个管道都有进出通道。每个访问都有一个文件描述符。当进程使用管道的一侧时,您必须使用 close() 关闭文件描述符。
    • 我必须关闭我使用过的管道的一侧或我没有使用的管道?
    • 现在清楚多了。您的示例确实帮助我了解何时应该关闭管道的每一侧。但是我仍然有问题。我使用了 4 个管道,在每个进程中,当我关闭未使用的管道的每一侧并尝试将主进程的字符串传递给每个子进程,然后返回主进程时,一切正常。当我使用 execlp 将字符串传递给每个进程的代码时,没有任何内容返回到主进程。在每个进程中,我使用 fgets 读取一个表达式并使用 printf 编写它。我重定向每个进程的标准输出。我的问题在哪里?
    • 没关系。我发现了我的问题。它在其中一个进程的代码中。我有一个不必要的 printf。非常感谢您的帮助。
    【解决方案2】:

    根据您的描述,我认为您想要链式分叉。例如。不是让主分叉三次来创建 p1、p2 和 p3,而是让主分叉一次来创建 p1,然后让 p1 分叉一次来创建 p2,它也分叉一次来创建 p3。

    【讨论】:

    • 感谢您的回答。我是流程新手,需要更多帮助。我该怎么做你的建议?请记住,我必须在 3 个子进程中的每一个中使用 execlp 来执行每个进程的代码。实际上我现在所做的是调用 fork 3 次并保存创建的进程的 id。然后在每个进程代码的代码中,在我调用 execlp 之前,我重定向我想要的输入和输出并关闭所有我不使用的管道。但我不确定我是否关闭并重定向一切正常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多