#include "apue.h"
int g_var = 6;
char buf[] = "a write to stdout\n";
int main(void){
int m_var = 0;
pid_t pid;
if (write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1)
err_sys("write error");
printf("before fork");
if ((pid = fork()) < 0){
err_sys("fork error");
} else if (pid == 0){
++g_var;
++m_var;
} else {
sleep(2);
}
printf("pid = %ld, g_var = %d, m_var = %d\n", (long)getpid(), g_var, m_var);
return 0;
}
1. 采用标准输出
输出结果为:
a write to stdout
before fork
pid = 15217, g_var = 7, m_var = 1
pid = 15216, g_var = 6, m_var = 0
2. 重定向标准输出
在 if(write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf) - 1)
语句对标准输出进行重定向:
stdout = freopen("./test.txt", "w", stdout);
此时最终的输出结果为:
a write to stdout
before fork
pid = 15177, g_var = 7, m_var = 1
before fork
pid = 15176, g_var = 6, m_var = 0
3. 解释
write 函数是不带缓冲的。在 fork 之前调用 write(write(STDOUT_FILENO, ...)
),所以其将数据写到标准输出一次。但,标准 IO 库是带缓冲的。
- 如果标准输出连到终端设备,则它是行缓冲的;
- 否则它是全缓冲的;
当以交互方式运行该程序时,只得到 printf("before fork\n")
输出的行一次,其原因是标准输出缓冲区由换行符冲洗。
但是当标准输出重定向到一个文件时,却得到printf 输出行两次。其原因是,在 fork 之前调用 printf 一次,但当调用 fork 时,该行数据仍在缓冲区中,然后在将父进程数据空间复制到子进程时,该缓冲区数据也被复制到子进程中。