【发布时间】:2011-10-12 01:15:28
【问题描述】:
我正在为需要一组 N 个子进程在基于 Unix 的系统上与其父进程通信的类编写 C++ 程序。为此,我在 fork 进程之前声明了两个由 N 个管道组成的数组,一个用于每个通信方向:
int pipesToParent[N][2];
int pipesToChild[N][2];
... // for int i = 0 to N-1, pipe(pipesToParent[i]), pipe(pipesToChild[i]),
// fork(), yada yada, I included error checking and everything.
int pipesToChild[N][2];
父进程的大部分代码都在一个while循环中;在这个循环的开始附近,它从特定进程中读取一条消息:
read(pipesToParent[processToServe][READ_END], charArray, BUF_SIZE);
它第一次通过循环,从进程 X 读取消息,它工作正常。然后它被指示对进程 Y 执行相同的操作,其中的消息包含与进程 X 完全相同类型的数据(我让每个进程在将其写入其管道时计算其消息),然后该进程就停止了。它没有退出,它只是在那条线上保持冻结状态。我已经尝试了我能想到的一切来弄清楚我发送的消息可能有什么问题,但看起来一切都很好。这是怎么回事?
(对不起,如果我的详细信息不充分;我不知道我还必须包括什么以及我可以删除哪些内容以粘贴会重现问题的内容。)
预计到达时间:
子进程有自己的内部while循环,它从自己的管道中读取:
read(pipesToChild[thisProcessNumber][READ_END], charArray, BUF_SIZE);
如果父母准备好了,它会发送消息:
write(pipesToParent[thisProcessNumber][WRITE_END], message, BUF_SIZE);
一些修补表明,进程 Y 与父进程非常相似,一次正常地通过此循环,然后在第二次读取时卡住了。冲洗究竟会做什么,如果我以这种方式写入/读取管道,我可以这样做吗? (如果相关,我已经#included cstdlib,但不是 cstdio。)
【问题讨论】:
-
要么你没有正确设置你的管道,要么进程 Y 没有真正写入数据,要么你有一个deadlock,或者其他错误。没有更多代码很难确定。
-
可能是进程 Y 出于某种原因没有向管道写入消息。从管道读取的进程将在等待数据显示在管道中时阻塞。我会确保 Y 真的在写入管道。
-
来自手册页,“请注意,默认情况下,输出 popen() 流是完全缓冲的。”写完后你 fflush() 吗?
-
我对使用类似数组的 C++ 设计持怀疑态度。您可能应该考虑每个进程都有一个与之关联的包含相关管道信息的结构,然后使用该结构的数组。除非在您的 C++ 课程中使用结构/类还为时过早,否则人们会想知道它们是如何教您的。
-
由于我们看不到您是如何设置孩子的,以及您是否关闭了足够多的文件描述符,因此很难通过远程控制来诊断您的问题。冻结可能是因为您的父进程正在从一个打开的文件描述符中读取,但该文件描述符不是 Y 写入其数据的那个。