【发布时间】:2018-04-09 22:53:11
【问题描述】:
在下面的程序中,调用了一个 fork() 并创建了一个孩子。我知道在 printf() 中使用缓冲输出时会出现不可预测的输出。为了解决这个问题,我使用了 write(),它是无缓冲的。
问题是 write() 没有将 \n 与字符串一起打印。
我尝试过使用 setvbuf() 来禁用缓冲标准输出,就像其他帖子建议的那样,我也尝试过使用 fflush(stdout)。但是输出总是一样的。
当我将输出重定向到这样的文件时
./main.out > output.txt
输出看起来不错。我知道这是可行的,因为在将输出重定向到文件时,系统通过缓冲整个输出来完成此操作,而不仅仅是行缓冲。
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#define NO_ERROR 0
#define BUFFER_SIZE 50
void childProcess();
void parentProcess();
int main(int argc, char * argv[])
{
int pid = (int) fork();
if(pid < 0)
{
puts("Error: Fork process failed");
}
else if (pid == 0)
{
childProcess();
}
else
{
parentProcess();
}
return NO_ERROR;
}
void childProcess()
{
char buffer[BUFFER_SIZE];
int pid = (int) getpid();
sprintf(buffer, "This line is from Child pid %d\n", pid);
write(1, buffer, strlen(buffer));
}
void parentProcess()
{
char buffer[BUFFER_SIZE];
int pid = (int) getpid();
sprintf(buffer, "This line is from Parent pid %d\n", pid);
write(1, buffer, strlen(buffer));
}
Cygwin 中的输出如下所示:(输出后还会打印 1 或 2 行新行)
This line is from Parent pid 20016This line is from Child pid 11784
预期输出:
This line is from Parent pid 20016
This line is from Child pid 11784
在另一台运行 linux 的机器上测试。输出看起来不同,但仍不如预期。提示后打印第二行。
user@server$ ./main.out
This line is from Parent pid 31599
user@server$ This line is from Child pid 31600
【问题讨论】:
-
在我的电脑上工作,也许在另一个终端模拟器上试试?
-
我认为这里的问题是即使
write没有被缓冲,这并不意味着操作系统在将其发送到终端之前不会在内部对其进行缓冲。获得可预测结果的唯一方法是同步父子节点和子节点,并在另一个完成写入时只让其中一个写入。 -
在这两条消息之后是否打印两个换行符?
-
@immibis 是的,确实如此,忘记提及了。有问题编辑
-
您看到的 Linux 输出是因为父级在打印后立即退出,而无需等待子级完成。因此,shell(等待父进程退出)继续并在子进程完成打印其字符串之前打印其提示。打印后向父级添加一个等待调用,您应该会得到更符合您预期的内容(尽管这些行可能以任一顺序出现)。