写一个程序,运用fork函数创建进程,分别在child和parent process中输出自己的pid。要求分别用write和printf输出,并且在执行的时候分别用重定向到文件和直接输出到终端的形式,观察输出结果并解释差异的原因。

1.设计思路

定义globvar和buf两个外部变量,然后利用write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1输出buf内容至屏幕,并且由于sizeof()会计算包括终止符null的长度,所以为了避免输出它,故将长度减1。接着printf输出一行字符串,然后利用pid存放fork函数返回的值,然后当它等于0时(也就是子进程),则将变量相加;否则它就是父进程,则另其睡眠2s,以使子进程先执行完毕(这不能保证子进程在2s内可以运行结束),最后再输出相关信息在exit程序即可。

2.结果分析

如图程序运行结果所示:write函数在fork函数之前调用,而write函数又是不带缓冲的,所以buf里面的只输出一次。printf在fork函数之前,对于直接输出到终端的形式,由于标准输出缓冲区由换行符冲洗,所以只得到printf的输出行一次,而由于子进程的数据是由父进程复制过去的,但是两者地址不同,所以会看到子进程的参数改变了,而父进程的没有改变。
在这里插入图片描述

而对于在执行时重定向到文件,buf的内容仍然只输出一次,原因同上。但是却得到printf两次,其原因其是在fork之前调用了一次,但当调用fork函数时,该数据仍然存在缓冲区,然后再将父进程的数据空间复制到了子程序,缓冲区的内容当然也会被复制过去,所以才会出现这种情况。而pid不同于上一次的是由于之前的进程ID被其他进程所占用,所以它只有往下寻找没有被占用的进程ID。

3.源码

#include "apue.h"

int globvar = 6;
char buf[] = "a write to stdout\n";

int main(void)
{
    int	var;
    pid_t pid;

    var = 88;
    if (write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1)
	err_sys("write error");
    printf("before fork\n");

    if ((pid = fork()) < 0)
	err_sys("fork error");
    else if (pid == 0)//子进程
    {
	globvar++;
	var++;
    }
    else             //父进程
        sleep(2);

    printf("pid = %ld, glob = %d, var = %d\n", (long)getpid(), globvar, var);
    exit(0);
}
Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐