C 多个子进程之间的管道

C 多个子进程之间的管道,c,operating-system,pipe,C,Operating System,Pipe,我试图通过不同的子进程来处理来自一位家长的输入。我能通过前三个孩子,但在那之后,我似乎无法得到任何输入或任何类似的东西 这是我的密码 #include <unistd.h> #include <stdio.h> #include <sys/wait.h> int main(int argc, char** argv) { pid_t pid; int pipes_1[2]; int pipes_2[2]; pipe(pipes_1); pipe(pipes

我试图通过不同的子进程来处理来自一位家长的输入。我能通过前三个孩子,但在那之后,我似乎无法得到任何输入或任何类似的东西

这是我的密码

#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>

int main(int argc, char** argv)
{
pid_t pid;
int  pipes_1[2];
int pipes_2[2];
pipe(pipes_1);
pipe(pipes_2);

switch(pid=fork())
  {
  case 0:
    dup2(pipes_1[0], 0);//copy stdin onto pipe 1 read
    dup2(pipes_2[1], 1);//copy stdout onto pipe 2 write
    close(pipes_1[0]);
    close(pipes_1[1]);
    close(pipes_2[0]);
    close(pipes_2[1]);

    execlp("sed", "sed","s/[^a-zA-Z]/ /g", "test.txt", (char*)NULL);

    break;

  default:
    break;
  }

switch(pid = fork())
  {
  case 0:
    dup2(pipes_2[0],0); //copy std onto pipes 2 read
    dup2(pipes_1[1],1);
    close(pipes_1[0]);
    close(pipes_1[1]);
    close(pipes_2[0]);
    close(pipes_2[1]);

    execlp("tr", "tr", "[A-Z]", "[a-z]", (char*)NULL);

    break;
  default:

    break;
  }
switch(pid=fork())
  {
  case 0:
    dup2(pipes_1[0], 0);
    dup2(pipes_2[1], 1);
    close(pipes_1[0]);
    close(pipes_1[1]);
    close(pipes_2[0]);
    close(pipes_2[1]);

    execlp("awk", "awk", "{for(i = 1; i <= NF; i++) {print $i;}}", (char*)NULL);
    break;
  default:

    break;
  }

switch(pid=fork())
  {
  case 0:
    dup2(pipes_2[0], 0);
    //dup2(pipes_1[1], 1);
    close(pipes_1[0]);
    close(pipes_1[1]);
    close(pipes_2[0]);
    close(pipes_2[1]);
    execlp("sort", "sort", (char*)NULL);
  default:
    break;
    }
wait();
return 0;
}
#包括
#包括
#包括
int main(int argc,字符**argv)
{
pid_t pid;
int pipes_1[2];
int pipes_2[2];
管道(管道1);
管道(管道2);
开关(pid=fork())
{
案例0:
dup2(管道1[0],0);//将标准数据复制到管道1上读取
dup2(pipes_2[1],1);//将标准输出复制到pipes 2写入
关闭(管道_1[0]);
关闭(管道1[1]);
关闭(管道_2[0]);
关闭(管道2[1]);
execlp(“sed”、“sed”、“s/[^a-zA-Z]//g”、“test.txt”、“char*)NULL);
打破
违约:
打破
}
开关(pid=fork())
{
案例0:
dup2(管道2[0],0);//将std复制到管道2上读取
dup2(管道1[1],1);
关闭(管道_1[0]);
关闭(管道1[1]);
关闭(管道_2[0]);
关闭(管道2[1]);
execlp(“tr”,“tr”,“[A-Z],[A-Z],(char*)NULL);
打破
违约:
打破
}
开关(pid=fork())
{
案例0:
dup2(管道1[0],0);
dup2(管道2[1],1);
关闭(管道_1[0]);
关闭(管道1[1]);
关闭(管道_2[0]);
关闭(管道2[1]);

execlp(“awk”、“awk”和“{for(i=1;i您似乎有一个管道:

sed … | tr … | awk … | sort
只需创建两个管道,其中需要三个管道。创建第三个管道并正确处理它,就可以了


调整第二个代码。注意,四个流程只需要三个管道(一般来说,N个流程需要N-1个管道)

样本输出:

sed:  74841
tr:   74842
awk:  74843
sort: 74844
PID 74841 died 0x0000
PID 74842 died 0x0000
PID 74843 died 0x0000
all
case
destiny
diarrhea
digital
gives
go
happy
lucky
missing
penultimate
upper
what
PID 74844 died 0x0000

进程ID信息主要是诊断信息。如果通过管道将程序的输出传输到过滤器,则会得到不同的输出(由于缓冲等原因),但区别在于排序数据与诊断信息的显示顺序。将诊断信息打印到标准错误,或添加
fflush(stdout)
每次之后
printf()
您将获得与显示的输出更为常规的类似结果。

现在我无法让awk提供任何输出您可能需要添加更新的代码。您可能在某个地方犯了一个简单的错误-例如可能忘记将
awk
的输出重定向到
排序的输入。这是不可能的e在没有看到代码的情况下进行猜测。但不要破坏原始代码;添加新的.4管道而不是3?我正在查看修订后的代码。没有足够的关闭。您需要关闭以前关闭的
管道3
管道4
的两端
管道1
管道2
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

static inline void error(const char *msg)
{
    perror(msg);
    exit(EXIT_FAILURE);
}

int main(void)
{
    int pid;
    int pipes_1[2];
    int pipes_2[2];
    int pipes_3[2];
    pipe(pipes_1);
    pipe(pipes_2);
    pipe(pipes_3);

    if ((pid = fork()) == 0)
    {
        dup2(pipes_1[1], 1);
        close(pipes_1[0]);
        close(pipes_1[1]);
        close(pipes_2[0]);
        close(pipes_2[1]);
        close(pipes_3[0]);
        close(pipes_3[1]);
        execlp("sed", "sed", "s/[^a-zA-Z]/ /g", "test.txt", (char *)NULL);
        error("Failed to exec sed");
    }
    printf("sed:  %d\n", pid);

    if ((pid = fork()) == 0)
    {
        dup2(pipes_1[0], 0);
        dup2(pipes_2[1], 1);
        close(pipes_1[0]);
        close(pipes_1[1]);
        close(pipes_2[0]);
        close(pipes_2[1]);
        close(pipes_3[0]);
        close(pipes_3[1]);
        execlp("tr", "tr", "[A-Z]", "[a-z]", (char *)NULL);
        error("Failed to exec tr");
    }
    printf("tr:   %d\n", pid);

    if ((pid = fork()) == 0)
    {
        dup2(pipes_2[0], 0);
        dup2(pipes_3[1], 1);
        close(pipes_1[0]);
        close(pipes_1[1]);
        close(pipes_2[0]);
        close(pipes_2[1]);
        close(pipes_3[0]);
        close(pipes_3[1]);
        execlp("awk", "awk", "{for(i = 1; i <= NF; i++) {print $i;}}", (char *)NULL);
        error("Failed to exec awk");
    }
    printf("awk:  %d\n", pid);

    if ((pid = fork()) == 0)
    {
        dup2(pipes_3[0], 0);
        close(pipes_1[0]);
        close(pipes_1[1]);
        close(pipes_2[0]);
        close(pipes_2[1]);
        close(pipes_3[0]);
        close(pipes_3[1]);
        execlp("sort", "sort", (char *)NULL);
        error("Failed to exec sort");
    }
    printf("sort: %d\n", pid);

    close(pipes_1[0]);
    close(pipes_1[1]);
    close(pipes_2[0]);
    close(pipes_2[1]);
    close(pipes_3[0]);
    close(pipes_3[1]);

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

    return 0;
}
Happy Go Lucky!
PENULTIMATE DESTINY@
missing all upper-case=
What gives?
Digital 023123098 Diarrhea
sed:  74841
tr:   74842
awk:  74843
sort: 74844
PID 74841 died 0x0000
PID 74842 died 0x0000
PID 74843 died 0x0000
all
case
destiny
diarrhea
digital
gives
go
happy
lucky
missing
penultimate
upper
what
PID 74844 died 0x0000