CSAPP作业:Fork函数的学习感悟

在CSAPP课程学习中,教材的第八章:异常控制流中出现了一个名为Fork的函数,在书中提到它可以将一个进程复制为几乎相同却不完全相同的两个进程,被用于系统调用错误处理中,这使我对它产生了浓厚的兴趣。
下面是对于书中fork函数的部分的个人理解:
调用:父进程通过调用fork函数创建一个新的运行的子进程。

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

pid_t fork(void);

fork函数只被调用一次却会返回两次,其中,子进程返回0,父进程返回子进程的PID,当发生错误时返回-1,返回值被用于区分父进程与子进程。
新创建的子进程与父进程几乎但是不完全相同。
子进程会得到与父进程用户及虚拟地址空间相同但是完全独立的一份副本,包括代码、数据段、堆、共享库和用户栈。
子进程可以读写父进程中打开的任何文件。
子进程与父进程的最大不同是PID不同。
如下是一个使用fork创建一个新进程的例子:

int main(){
	pid_t pid;
	int x = 1;
	pid = Fork();
	if (pid == 0){
		//Child
		printf("child : x=%d\n",++x);
		exit(0);
	}
	//Parent
	printf("parent : x=%d\n",--x);
	exit(0);
}

运行结果:

linux> ./fork
parent : x=0;
child : x=2;

这个例子其中的一些规律:
fork函数被调用了一次但是出现了两次返回;
父进程与子进程是并发执行的;
父进程与子进程具有相同但是相互独立的地址空间,正如上文所说,子进程会得到与父进程用户及虚拟地址空间相同但是完全独立的一份副本,但是由于子进程与父进程的地址空间是相互独立的,所以当进程执行时,对于变量等所做的任何改变都是相互独立互不干涉的,不会反映在对方的进程内存中,因此可见最后子进程与父进程输出的x值是不同的。
父进程与子进程共享文件,所以他们都在屏幕上进行了输出。

再来看看另一个例子:

int main(){
	int x =  1;
	if(Fork()==0)
		printf("p1:x=%d\n",++x);
	printf("p2:x=%d\n",--x);
	exit(0);
}

这个例子中需要注意的是,我们使用了第一个if语句来判断fork()的返回值,依据上文我们可以知道,当fork返回值为0时,表示这个是子进程,而在这块代码中,if语句判断完成后会执行第一句printf,因此我们可知第一句printf属于子进程,但是父进程呢?父进程则不会进入if语句中,所以父进程的代码只执行第二条printf,与此同时我们知道子进程与父进程会共享代码,因此父进程仅有的这个printf也会被子进程复制一份再执行一次,因此我们可知最后的运行输出结果为:
p1:x=2
p2:x=1 //这两行是子进程的输出结果
p2:x=0 //这一行是父进程的输出结果

通过这两个例子,我们可以大致明白fork函数的作用了,那么回到课本上对于调用fork函数进行系统调用错误处理的部分:
pid = Fork();
我们展开这个函数:

pid_t Fork(void)
{
	pid_t pid;
	if ((pid = fork()) < 0)
		unix_error("Fork error");
	return pid;
}

void unix_error(char *msg) //Unix_style error
{
	fprintf(stderr, "%s : %s\n",msg,strerror(errno));
	//strerror()为错误报告函数
	exit(0);
}

可以看到在此当我们调用一次fork函数时,我们运行的进程会自动再创建一个子进程,当我们的程序出现系统调用错误时,如果不调用fork,Unix系统通常会直接将函数返回-1,但是如果调用了fork函数,我们将可以在出错时利用到子进程中的错误报告函数来向我们报告具体发生了什么错误,并且也不会影响父进程的正常运行。

以上就是本人对于fork函数知识点的学习感悟。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值