一个好玩的fork

最近课堂上学到了这个好玩的函数,于是就真的开始玩起来了。。。
首先是这个函数的官方解说:
fork系统调用用于创建一个新进程,称为子进程,它与进程(称为系统调用fork的进程)同时运行,此进程称为父进程。创建新的子进程后,两个进程将执行fork()系统调用之后的下一条指令。子进程使用相同的pc(程序计数器),相同的CPU寄存器,在父进程中使用的相同打开文件。
关于这个,我们Linux书上有一个形象的比喻:
随着一句fork,一个新进程呱呱落地,但这时它只是老进程的一个克隆。
不过汉字文化博大精深,还是不大明白的亚子,,于是我就找了几个比较典型的例子跑了一跑:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>

int main(int argc, char *argv[])
{
    pid_t pid;
    int x = 1;

    pid = Fork(); 
    if (pid == 0) 
	printf("child : x=%d\n", ++x); 
	fflush(stdout);
	return 0;
    }

    printf("parent: x=%d\n", --x); 
    fflush(stdout);
    return 0;
}

结果如下:
在这里插入图片描述
这个时候就变得好玩了。
可见fork被调用一次,却能够返回两次。根据老师的说法,fork可能有三种不同的返回值:
1.在父进程中,fork返回新创建子进程的进程ID;
2.在子进程中,fork返回0;
3.如果出现错误,fork返回一个负值;
两次是能理解了,但结果呢?于是我又翻了一下另一堂课的书,结合老师的说法,得出了这样的结论:
fork的作用是复制一个进程,两个进程是并发执行的,而且Linux是使用写时复制来实现fork的。那么其实这两个进程其实可以分开来看,各干各的,只是初始值一样而已。大致是这样:
在这里插入图片描述
这样就很好理解了吧!
后面我又跑了几个其他fork函数,代码和结果如下:

void fork0() 
{
    if (fork() == 0) {
	printf("Hello from child\n");
    }
    else {
	printf("Hello from parent\n");
    }
}

fork0运行结果

void fork1()
{
    int x = 1;
    pid_t pid = fork();

    if (pid == 0) {
	printf("Child has x = %d\n", ++x);
    } 
    else {
	printf("Parent has x = %d\n", --x);
    }
    printf("Bye from process %d with x = %d\n", getpid(), x);
}

fork1运行结果

void fork2()
{
    printf("L0\n");
    fork();
    printf("L1\n");    
    fork();
    printf("Bye\n");
}

fork2运行结果
注意fork2这个函数我放出的两个运行结果不一样,原因就是我刚刚说的“两个进程并发执行”,注意“复制”和“并发”两个关键字,是fork最基本的要点,如果有很难分清的情况,就可以像我琢磨第一个代码一样画一个能分清的图。。。
不过我这是跑了最基础且典型的代码,不够深层,这位前辈的会更深层哦~
https://blog.csdn.net/jason314/article/details/5640969

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值