fork简介

在类UNIX的操作系统中,父进程通过调用fork 函数创建一个新的运行的子进程。父进程和新创建的子进程之间最大的区别在于他们有不同的PID。

fork的应用

下面让我们来看fork简单的应用吧!!!

fork.c

#include "csapp.h"

int main(int argc, char *argv[]) 
{
    pid_t pid;
    int x = 1;
	pid = Fork(); //line:ecf:forkreturn
	if (pid == 0) {  /* Child */
		printf("child : x=%d\n", ++x); //line:ecf:childprint
		fflush(stdout);
		return 0;
	}

	/* Parent */
	printf("parent: x=%d\n", --x); //line:ecf:parentprint
	fflush(stdout);
	return 0;
}

csapp.hcsapp.c文件在此就不展示了!!

让我们编译一下gcc -o fork fork.c csapp.c 就可得到一个可执行文件fork

执行fork文件 ./fork

可以看到父进程比子进程先执行(实际这个是不一定的),变量x在两个进程中运行结果不同。

它的程序进程图可看出:

在调用fork函数后,x=1分别进入父进程和子进程,x在父进程中执行--x操作,所以它的值为0

x在子进程中执行++x操作,所以它的值为2

经过上面的例子你可能一知半懂了,下面让我们来看看 面试题吧!

numOfStar1.c

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main(){
	int i;
	for(i = 0;i < 2;i++){
		fork();
		printf("*\n");
	}
	return 0;
}

我们将得到结果为:

它的结果为6颗*

我们来看看它的进程图:

从中我们可以看到有6printf,而且printf中有\n,所以打印了6个*

注:printf 函数在打印时,不会直接打印到屏幕上,而是放在缓存区中,当遇到\n 或程序结束时将缓存中的数据推入到屏幕。所以当代码中没有\n时,不是输出6个*。

如下:

numOfStar2.c

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main(){
	int i;
	for(i = 0;i < 2;i++){
		fork();
		printf("*");
	}
	return 0;
}

可以看到打印了8个*。

看了几个简单的,我们来看个复杂点的吧!

forkStar.c

int main(){
	fork();
	fork()&&fork()||fork();
	fork();
	printf("*\n");
	return 0;
}

这个的结果是20个*

造成这个结果的原因是&&||是短路运算符。A&&B:当A为假时B不会再执行了。

A||B:当A为真时,B不会再执行了。

这时我们可以画出其进程图:(注:为区分使用的fork函数,将上述代码中fork出现位置分别标记为fork1 , fork2...)

一共有20个printf