C:dup2,管道和fork没有按预期工作

pis*_*hio 7 c fork pipe

我正在尝试做一个简单的fork - >执行另一个程序 - >对那个子进程说"hello" - >回读一些东西 - >打印收到的东西.

用作孩子的程序只是等待任何输入行,并向stdout打印一些东西,比如"你好!"

这是我的"主机"程序(不起作用):

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

#define IN 0
#define OUT 1
#define CHILD 0

main ()
{
  pid_t pid;
  int pipefd[2];
  FILE* output;
  char buf[256];

  pipe(pipefd);

  pid = fork();    
  if (pid == CHILD)
  {
    printf("child\n");
    dup2(pipefd[IN], IN);
    dup2(pipefd[OUT], OUT);
    execl("./test", "test", (char*) NULL);
  }
  else
  {
    sleep(1);
    printf("parent\n");
    write(pipefd[IN], "hello!", 10); // write message to the process    
    read(pipefd[OUT], buf, sizeof(buf));
    printf("received: %s\n", buf);
  }
}
Run Code Online (Sandbox Code Playgroud)

我明白了:

child
[.. waits 1 second ..]
parent
received: 
Run Code Online (Sandbox Code Playgroud)

我错过了什么?谢谢!

编辑(test.c):

根据要求,这是儿童计划:

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

int getln(char line[])
{
  int nch = 0;
  int c;

  while((c = getchar()) != EOF)
    {
      if(c == '\n') break;
    line[nch] = c;
    nch++;
    }

 if(c == EOF && nch == 0) return EOF;
 return nch;
}

main()
{
  char line[20];

  getln(line);
  printf("hello there!", line);
  fflush(stdout);  
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

Jas*_*son 4

您总是假设从 file-descriptor 读取0,并使用管道写入 file-descriptor 1...您在父进程中颠倒了这种关系。对于您想要做的事情,您最终可能需要两个管道来进行父级和子级之间的双向通信,以避免父级最终读取其写入管道的内容的情况,因为进程调度是不确定的(即,如果父级也从同一管道读取,则不能保证子级能够读取父级写入管道的内容,因为父级可能只是最终写入然后读取,而不会交错子进程来读取父级的内容写道)。

将您的代码更改为以下内容:

main ()
{
  pid_t pid;
  int pipe_to_child[2];
  int pipe_from_child[2];
  FILE* output;
  char buf[256];

  pipe(pipe_to_child);
  pipe(pipe_from_child);

  pid = fork();    
  if (pid == CHILD)
  {
    printf("child\n");

    //child process not using these ends of the pipe, so close them
    close(pipe_to_child[1]);
    close(pipe_from_child[0]);

    dup2(pipe_to_child[0], fileno(stdin));
    dup2(pipe_from_child[1], fileno(stdout));

    execl("./test", "test", (char*) NULL);
  }
  else
  {
    sleep(1);
    printf("parent\n");
    write(pipe_to_child[1], "hello!\n", 10); // write message to the process    
    read(pipe_from_child[0], buf, sizeof(buf));
    printf("received: %s\n", buf);
  }
}
Run Code Online (Sandbox Code Playgroud)