C:dup2,管道和叉未正常工作 [英] C: dup2, pipe and fork not working as expected

查看:118
本文介绍了C:dup2,管道和叉未正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图做一个简单的叉 - >运行另一个程序 - >说你好向子进程 - >回读的东西 - >打印收到的是什么

作为孩子的计划只是等待任何输入线和输出的东西,如标准输出你好!

这是我的主人计划(即不工作):

 的#include< SYS / types.h中>
#包括LT&;&unistd.h中GT;
#包括LT&;&stdio.h中GT;#定义IN 0
#定义OUT 1
#定义儿童0main()的
{
  将为pid_t PID;
  INT pipefd [2];
  FILE *输出;
  焦炭BUF [256];  管(pipefd);  PID =叉();
  如果(PID == CHILD)
  {
    的printf(子\\ n);
    dup2(pipefd [IN],IN);
    dup2(pipefd [OUT],OUT);
    EXECL(./测试,测试,(字符*)NULL);
  }
  其他
  {
    睡眠(1);
    的printf(父\\ n);
    写(pipefd [IN],你好!,10); //写消息的过程
    阅读(pipefd [OUT] buf中,sizeof的(BUF));
    的printf(接受:%S \\ n,BUF);
  }
}

我得到这样的:

 
[..等待1秒..]

好评:

我在想什么?谢谢!

修改(test.c的):

根据要求,这是孩子的程序:

 的#include<&stdio.h中GT;
#包括LT&;&string.h中GT;
#包括LT&;&stdlib.h中GT;INT getln(焦线[])
{
  INT NCH = 0;
  INT℃;  而((C =的getchar())!= EOF)
    {
      如果(C =='\\ n')打破;
    行[NCH] = C;
    NCH​​ ++;
    } 如果(C == EOF和放大器;&安培; NCH == 0)返回EOF;
 返回NCH;
}主要()
{
  焦线[20];  getln(线);
  的printf(你好!,线);
  fflush(标准输出);
  返回0;
}


解决方案

你总是想从文件描述符 0 来读取和写入到文件描述符 1 与管......你有这样的关系在父进程逆转。对于你想,做什么,你可能最终需要两个管道对于其中母公司结束了阅读它,因为进程调度写信给管道的内容,避免局势的父母和孩子之间的双向沟通​​是不确定性(也就是说,孩子不能保证读什么家长写信给管道如果父也从同一管道读书,因为家长可能只是写出来,然后用无交织子进程的阅读,读什么父写)。

更改code以下内容:

 的main()
{
  将为pid_t PID;
  INT pipe_to_child [2];
  INT pipe_from_child [2];
  FILE *输出;
  焦炭BUF [256];  管(pipe_to_child);
  管(pipe_from_child);  PID =叉();
  如果(PID == CHILD)
  {
    的printf(子\\ n);    //子进程不使用管道的这些目的,所以他们关闭
    关闭(pipe_to_child [1]);
    关闭(pipe_from_child [0]);    dup2(pipe_to_child [0],的fileno(标准输入));
    dup2(pipe_from_child [1],的fileno(标准输出));    EXECL(./测试,测试,(字符*)NULL);
  }
  其他
  {
    睡眠(1);
    的printf(父\\ n);
    写(pipe_to_child [1],你好\\ N!,10); //写消息的过程
    读(pipe_from_child [0],buf中,的sizeof(buf中));
    的printf(接受:%S \\ n,BUF);
  }
}

I'm trying to do a simple fork -> execute another program -> say "hello" to that child process -> read back something -> print what received.

The program used as child just waits for any line of input and prints something to the stdout like "hello there!"

This is my "host" program (that is not working):

#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);
  }
}

I get this:

child
[.. waits 1 second ..]
parent
received: 

What am I missing? Thanks!

EDIT (test.c):

By request, this is the child program:

#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;
}

解决方案

You're always suppose to read from file-descriptor 0, and write to file-descriptor 1 with pipes ... you have this relationship reversed in the parent process. For what you're wanting to-do, you may end up needing two pipes for two-way communication between the parent and child that avoids situations where the parent ends up reading the contents it wrote to the pipe since process scheduling is non-deterministic (i.e., the child is not guaranteed to read what the parent wrote to the pipe if the parent is also reading from the same pipe since the parent could just end up writing and then reading with no interleaving of the child process to read what the parent wrote).

Change your code to the following:

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);
  }
}

这篇关于C:dup2,管道和叉未正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆