【问题标题】:C Programming 2 pipesC 编程 2 个管道
【发布时间】:2013-04-22 01:46:55
【问题描述】:

我想在我的程序中设置 2 个管道。我有 1 个管道工作正常,但我不知道在哪里放置第二个管道。

我的设置的伪代码如下所示,

这里是带花括号的,抱歉

//the first pipe:   
pipe(pipe1) 

//the second pipe:  
pipe(pipe2) 

pid = fork()

if(pid == 0) {

  dup2(pipe1[1], 1)
  close(pipe1[0])
  execvp(beforepipe)
  }  

if(pid > 0) { //everything below is in here

  pid2 = fork()

  if(pid2 == 0){

    //pipe1
    dup2(pipe1[0],0)
    dup2(out,1)
    close(pipe1[1])
    execvp(afterpipe)

    //pipe2 does not work might need to be placed in different area
    dup2(pipe1[1],1)
    close(pipe1[0])
    execvp(beforepipe1)
    }

  if(pid2 > 0){
    close(pipe[0])
    close(pipe[1])
    wait() //this is an infinite for loop

    pid3 = fork()

    if(pid3 == 0){
      dup2(pipe2[0],0)
      dup2(out,1)
      close(pipe2[1])
      execvp(afterpipe2)
      }

    if(pid3 > 0) {
      close(pipe2[0])
      close(pipe2[1])
      wait()
      }
    }

第二个管道的位置错误或代码完全错误。

有什么建议吗?

【问题讨论】:

  • 你到底想做什么?你能展示一下管道应该是什么样子吗? (例如<program1> ->pipe1-> <program2> ->pipe2-> <program3> 让程序 1 通过管道 1 写入程序 2,程序通过管道 2 写入程序 3)
  • /ma/cs570/Data1/input1 cat|tr a-z A-Z | tr \\ q > your.outputc 这是我要开始工作的命令。基本上,第一个管道将 input1 中的“eschew obfuscation\”转换为“eschew OBFUSCATION\”。第二个管道用 q 替换“\”以获得“ESCHEW OBFUSCATIONq”。第一个管道正在工作,但第二个没有。
  • 我还得到“tr:当不截断 set1 时,string2 在输出中必须非空”以及 your.outputc 中的“ESCHEW OBFUSCATION\”
  • 我得到 tr 错误的原因是因为 "\\" 被跳过并且 tr 后面需要 2 个字符串。会努力修复这个错误

标签: c operating-system pipe execvp dup2


【解决方案1】:

您的主要问题是您没有关闭足够多的文件描述符。给定当前目录中包含您的字符串“eschew obfuscation\”的文件input1,此代码适用于我(但请注意必须关闭多少文件描述符!)。

  • 经验法则:如果管道是dup2()d 或dup()d 到标准输入或输出,则关闭两个文件管道文件描述符。

示例代码(带有调试跟踪):

#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

/* command pipeline: cat input1 | tr a-z A-Z | tr \\ q */

int main(void)
{
    int pipe1[2];
    int pipe2[2];
    pid_t pid1;
    char *cmd1[] = { "cat", "input1",        0 };
    char *cmd2[] = { "tr",  "a-z",    "A-Z", 0 };
    char *cmd3[] = { "tr",  "\\",     "q",   0 };

    if (pipe(pipe1) != 0 || pipe(pipe2) != 0)
    {
        perror("pipe failed");
        return 1;
    }

    pid1 = fork();

    if (pid1 < 0)
    {
        perror("fork 1 failed");
        return 1;
    }

    if (pid1 == 0)
    {
        /* Child 1 - cat */
        dup2(pipe1[1], 1);
        close(pipe1[0]);
        close(pipe1[1]);
        close(pipe2[0]);
        close(pipe2[1]);
        execvp(cmd1[0], cmd1);
        perror("failed to execute cmd1");
        return 1;
    }

    printf("pid 1 = %d\n", pid1);
    fflush(stdout);

    pid_t pid2 = fork();
    if (pid2 < 0)
    {
        perror("fork 2 failed");
        return 1;
    }

    if (pid2 == 0)
    {
        /* Child 2 - tr a-z A-Z */
        dup2(pipe1[0], 0);
        dup2(pipe2[1], 1);
        close(pipe1[0]);
        close(pipe1[1]);
        close(pipe2[0]);
        close(pipe2[1]);
        execvp(cmd2[0], cmd2);
        perror("failed to execute cmd2");
        return 1;
    }

    printf("pid 2 = %d\n", pid2);
    fflush(stdout);

    pid_t pid3 = fork();
    if (pid3 < 0)
    {
        perror("fork 3 failed");
        return 1;
    }

    if (pid3 == 0)
    {
        /* Child 3 - tr \\ q */
        dup2(pipe2[0], 0);
        close(pipe1[0]);
        close(pipe1[1]);
        close(pipe2[0]);
        close(pipe2[1]);
        execvp(cmd3[0], cmd3);
        perror("failed to execute cmd3");
        return 1;
    }

    printf("pid 3 = %d\n", pid3);
    fflush(stdout);

    /* Parent - wait for the kids to all die */
    close(pipe1[0]);
    close(pipe1[1]);
    close(pipe2[0]);
    close(pipe2[1]);

    pid_t corpse;
    int   status;
    while ((corpse = wait(&status)) > 0)
        printf("Child %d died status 0x%.4X\n", corpse, status);

    return 0;
}

【讨论】:

  • 非常感谢@Jonathan Leffler
【解决方案2】:
execvp(afterpipe)
//pipe2 does not work might need to be placed in different area
dup2(pipe1[1],1)
close(pipe1[0])
execvp(beforepipe1)

我认为 execvp() 没有返回。所以 execvp() 下面的代码是无关紧要的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-08
    相关资源
    最近更新 更多