【发布时间】:2018-10-28 18:35:02
【问题描述】:
我有以下输出代码:
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <wait.h>
#define PIPE_STDIN 0
#define PIPE_STDOUT 1
#define msg "hello world"
int main()
{
int fd_pipe[2];
int ret = fork();
if (ret < 0)
{
printf("Failed to fork\n");
return -1;
}
else if (ret == 0)
{
printf("Parent with PID %d\n", getpid()); fflush(stdout);
//sleep(3);
ret = write(fd_pipe[PIPE_STDOUT], msg, sizeof(msg)); fflush(stdout);
printf("Parent wrote string %d\n", ret); fflush(stdout);
wait( NULL );
printf("Parent done wait\n"); fflush(stdout);
}
else
{
char buf[80];
printf("Child with PID %d whose parent PID %d\n", getpid(), ret); fflush(stdout);
ret = read(fd_pipe[PIPE_STDIN], buf, sizeof(msg));
printf("Child read %s %d\n", buf, ret); fflush(stdout);
}
}
输出:
Child with PID 1130 whose parent PID 1131
Child read -1
Parent with PID 1131
hello world Parent wrote string 12
Parent done wait
从输出中,为什么 child 无法从管道读取(返回 -1),然后打印了消息“hello world”?请解释给出上述日志的执行顺序。
【问题讨论】:
-
你没有显示你在哪里调用
pipe()——你使用的是随机文件描述符。 -
在
write()调用之后的fflush(stdout)基本上是空操作。 -
常识规定
fork()的结果是子进程的pid号,因为父进程pid总是可以通过getppid()系统调用得到,但是没有办法得到UNIX 中孩子的 pid,但直接从fork()syscall 获取。 -
@JonathanLeffler,
write()在fflush()实施之下。它对缓冲区一无所知(它不是stdio的一部分),因此如果您仅执行write(2)系统调用,缓冲区中可能会有数据。如果他改用fwrite(3),那就没什么好说的了。 -
@LuisColorado — 是的,但是
write()之前的电话也是fflush(stdout),所以正如我所说,之后的电话无关紧要。