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