【问题标题】:transferring a pipe between parent and child within a function在函数内的父子之间传输管道
【发布时间】:2015-03-26 11:18:40
【问题描述】:

我在以下事情上遇到了一些困难:
我正在尝试将管道发送到函数内的子节点,然后让子节点写入其中。
以下代码部分会更好地解释它:

int p[2];
int i;
pipe(p);
close(p[1]);
if(fork1() == 0){
  close(p[0]);
  runcmd(parsecmd(buf),p);
}
wait(0);
}
while(read(p[0],&i,sizeof(int)) != 0){
printf(1," id: %d\n",i );}

runcmd 将有以下代码:

...
void runcmd(struct cmd *cmd,int pp[]){
int j = getpid();
write(pp[1],&j,sizeof(int));
close(pp[1]);
...

遗憾的是,预期的结果应该是 - 父级将打印 id(getpid 是一个返回当前正在运行的进程 id 的函数),但事实并非如此,它在调用时什么也不打印。我做错什么了?

【问题讨论】:

  • 我不认为wait(0); 是允许的。我没有在手册页中找到可以将 NULL 指针传递给 wait()
  • wait(0) 是允许的,因为它是 xv6 而不是普通的 linux...

标签: c pipe fork read-write xv6


【解决方案1】:

在分叉之前关闭管道的写入端,这样子进程就无法写入它。您还需要exit() 孩子。所以你的代码应该是某事。像这样:

pipe(p);
if(fork1() == 0){
   close(p[0]);
   runcmd(parsecmd(buf),p);
   exit(0);  
}
close(p[1]);
...

除了我建议添加一些错误处理(fork() 也可能返回 -1)`

编辑:这适用于 Linux

void runcmd(int pp[])
{
    int j = getpid();
    write(pp[1],&j,sizeof(int));
    close(pp[1]);
    exit(0);
}

int main( int argc, char *argv[] )
{
    int p[2];
    int i;
    int status;

    pipe(p);
    if(fork() == 0){  // for linux: fork() instead of fork1()
       close(p[0]);
       runcmd(p);
    }
    close(p[1]);      // close belongs here
    wait(&status);    // Linux: wait(0) is not allowed
    while(read(p[0],&i,sizeof(int)) > 0)  // != 0 causes endless loopn on EOF
    {
         printf(" id: %d\n",i );   // first parameter '1' doesn't belong there
    }
    return( 0 );
}

【讨论】:

  • 我移动了 close(p[1]),但它仍然不起作用。孩子在其中退出(在runcmd中)......所以这些不是导致问题的原因。
  • 究竟发生了什么? read() 挂起还是返回 0?
  • 可能问题出在您尚未发布的代码中。我已经为你的代码创建了一个 Linux 版本,它运行良好——查看我的编辑
  • 我认为问题可能出在指针上...用 (int pp[]) 可以吗?
  • 不,应该没问题;当然将p[1] 传递给runcmd() 就足够了
【解决方案2】:

问题已经解决了!
麻烦的部分是 while 循环是在“等待”调用之后,而不是之前,在改变它之后它就像魔术一样工作!
感谢您的帮助!

【讨论】:

    猜你喜欢
    • 2012-10-03
    • 2019-09-02
    • 1970-01-01
    • 2015-05-19
    • 2020-04-09
    • 1970-01-01
    • 2015-05-10
    • 2017-08-26
    • 1970-01-01
    相关资源
    最近更新 更多