【问题标题】:Pipe is not working correctly in the parent-child process管道在父子进程中无法正常工作
【发布时间】:2014-08-17 08:48:48
【问题描述】:

由于我刚刚开始了解这些概念,我可能会遗漏一些基本的东西。我试图使用管道链接父进程和子进程(由 fork() 函数创建)。在父进程中,我想写入管道描述符(af[1]),在关闭写入端后,我想在子进程中使用描述符(af[0])从管道的读取端读取。

这是我的代码:

#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <cstdlib>
#include <sys/wait.h>
#include <sys/types.h>
#include <string.h>
using namespace std;

int main()
{
    pid_t pid1;
    pid1 = fork();

    int af[2],nbytes,wbytes;
    pipe(af);
    char inside[20];

    if(pid1 == -1)
    {
        cout << "No child process formed: " << getpid() <<endl;
        exit(1);
    }
    else if(pid1 == 0)
    {   cout<< "inchild" <<endl;
        close(af[1]);
        nbytes = read(af[0],inside,strlen(inside));
            cout << "read bytes: "<< nbytes << endl;
        cout << "child(read) inside descriptor: " << inside << endl;
        close(af[0]);
        cout << "in child's end" << endl;
        exit(0);
    }   
    else
    {   cout<< "inparent" << endl;
        close(af[0]);
        wbytes = write(af[1],"Hello World",12);
        cout<< "wrote bytes: " << wbytes<<endl;
        cout << "Parent(write) inside string: " << af[1] << endl;
        close(af[1]);
        cout << "in parent's end" << endl;
        exit(0);
    }

    return 0;

}

然后我期望它运行如下:

  • 进入父级 -> 写入字符串,
  • 关闭写入端,
  • 进入孩子 -> 将字符串读入inside
  • 显示字符串结果 (Hello World),
  • 关闭阅读结束。

但我得到的是这个结果:

inparent
shashish-vm@shashishvm-VirtualBox:~/Desktop$ inchild
read bytes: 0
child(read) inside descriptor: 
                               A��M�N��sf�
in child's end

它仍然没有结束。

我在 Oracle VM VirtualBox(32 位操作系统)上使用 Ubuntu 14.04 LTS。而且我不知道为什么会这样。我知道切换进程是调度程序的工作,但 IPC 的管道功能仍然无法正常工作。即使我删除了close(af[0]) 语句,写入过程仍然发生,但读取仍然没有正确进行。

【问题讨论】:

  • sizeof(inside) not strlen(inside) in read() 通话
  • 在 C++ 中,char 大小为 1 字节,因此无关紧要。但是,是的,理想情况下,我应该使用它。谢谢。
  • 这很重要。 inside 被单元化,所以 strlen() 返回垃圾值,你可以得到所有不可预知的结果,包括程序崩溃。
  • 是的。这是孩子比父母更早安排的情况之一。但是调度程序在这里以另一种方式工作。因此,它已经在父级中分配了一个值。所以,是的,我应该处理好这件事。谢谢您的帮助。 :-)
  • 首先你不要在父进程中触摸inside。其次 - 没关系,因为在fork() 之后,它们是两个独立的进程,并且在一个进程中更改内存不会影响另一个进程(除非它是另一个 IPC - 共享内存)。他们如何安排完全无关。第三,在这种情况下使用 strlen() 无论如何都不是一个好主意,即使它已正确初始化。

标签: c++ linux fork pipe


【解决方案1】:

你的问题是你在调用 fork 之后打开了管道。这意味着父母和孩子有不同的管道。您可以通过在 fork 之前将调用移至 pipe 以创建单个链接管道来修复它。

【讨论】:

  • 哦!我应该注意到了。在 fork 语句之后,所有事件都作为单独的事件开始。谢谢您的帮助。 :)
猜你喜欢
  • 2020-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-20
  • 1970-01-01
  • 2023-01-19
  • 2017-04-28
  • 1970-01-01
相关资源
最近更新 更多