【问题标题】:Executing wc command on child process using pipeline使用管道在子进程上执行 wc 命令
【发布时间】:2016-04-13 16:04:11
【问题描述】:

我正在编写一个对子进程执行字数统计命令的程序。父进程应该将用户通过管道输入的一系列行发送到子进程。 我试图这样做,但我最终遇到了一个错误。 这是我的代码:

int main ()
{
    int fd[2];
    char buff;
    int pid;
    int pip;
    pid = fork();
    pip = pipe(fd);

    if (pid != 0)
    {
        pip = pipe(fd);
        if (pipe == 0)
        {
            while (read(fd[0], &buff,1) > 0 )
            {
                write (fd[1],&buff,1);      
            }
            close(fd[0]);
            _exit(0);
        }
    }
    else
    {
        dup2(fd[1],1);
        close(fd[1]);
        execlp ("wc","wc",NULL);
        _exit(-1);
    }
    return 0;
}

我还尝试使用dup2 将来自子进程的标准输入与父进程创建的管道的读取描述符相关联。 但我收到此错误:wc: standard input: Input/output error我该如何解决这个问题?

已更新(错误已解决,但我得到一个无限循环)

int main ()
{
    int fd[2];
    char buff;
    int pid;
    int pip;

    pip = pipe(fd);

    if (pip == 0)
    {
             pid = fork();
         if (pid != 0)
          {     

            while (read(fd[0], &buff,1) > 0 )
            {
                write (fd[1],&buff,1);      
            }
            close(fd[0]);

          }
          else {

        dup2(fd[1],1);
        close(fd[1]);
        execlp ("wc","wc",NULL);
        _exit(-1);
          }
    }
    return 0;
}

【问题讨论】:

  • 为什么在同一个 fd 数组上调用 pipe() 两次?为什么要先分叉然后创建管道?在一个线程中创建管道并在另一个线程中使用它对竞争条件开放。
  • @WernerHenze 你说得对,管道是由父进程创建的。我的错。
  • @WernerHenze,比你说的更糟糕,因为这里没有线程,因此没有共享数据。子进程将永远在其数组副本中看到第二个 pipe() 调用的效果,并且通过进行该调用,父进程会将管道的 FD 丢失给子进程。
  • @JoséCunha 如果您更改了代码,请更新您的问题。
  • 您的文件描述符处理已损坏。请考虑哪个进程应该从哪里(控制台,管道)读取并写入到哪里(控制台,管道)。绘制图表可能会有所帮助。然后尝试将其与您的代码相匹配,并考虑从哪里读取/写入文件 0、1、fd[0] 和 fd[1]。

标签: c fork pipeline wc


【解决方案1】:
#include <unistd.h>

int main ()
{
    int fd[2];
    char buff;
    int pid;
    int pip;
    int status;

    pip = pipe(fd);

    if (pip == 0)
    {
        pid = fork();
        if (pid != 0)
        {
            close(fd[0]);
            while (read(0, &buff,1) > 0 )
            {
                write (fd[1],&buff,1); /* your old loop forwarded internally in the pipe only*/
            }
            close(fd[1]);
         } else {
             dup2(fd[0],0);  /* you had dup2(fd[1], 1), replacing stdout of wc with the write end from wc */
             close(fd[0]);
             close(fd[1]);
             execlp ("wc","wc",NULL);
             _exit(-1);
          }
    }
    wait(&status); /* reap the child process */
    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-12
    • 2020-12-07
    • 2020-03-08
    • 1970-01-01
    • 2016-03-04
    • 1970-01-01
    • 2011-04-16
    • 1970-01-01
    相关资源
    最近更新 更多