fork,写时复制(copy-on-write),vfork

fork,写时复制(copy-on-write),vfork

进程创建

进程创建分为三种情况
1.共享
父进程与子进程共享数据段、堆栈段、代码段,也就是说子进程对数据进行的改变会直接影响父进程。
2.写时复制(Copy-On-Write)
我简单地将这种技术理解为,当子进程执行写操作时,内核会将被修改的部分单独copy,单独操作。
3.直接拷贝
直接复制父进程的数据段、堆栈段,共享代码段。

一、fork

fork()调用时,子进程会复制父进程数据段、堆栈段,并且使用新的物理地址以及虚拟地址存储。但父子进程共享代码段。但现在的实现采用了写时复制技术

二、vfork

vfork()调用时,父子进程共享所有资源。但在调度上,使用vfork将保证子进程先于父进程被调度。

下面给出参考书的代码用以说明两者区别:

  • fork
	/**********************************************************************

		> File Name: t_fork.c

		> Author: 0nism

		> Email: fd98shadow@sina.com

		> Created Time: Sun 14 Oct 2018 02:41:39 PM CST

	***********************************************************************/

	#include <unistd.h>
	#include <stdio.h>
	#include <stdlib.h>

	static int idata = 111;         //  Allocated in data segment

	int main(int argc, char **argv)
	{
		int istack = 222;           //  Allocated in stack segment
		pid_t childPid;

		switch (childPid = fork())
		{   
			case -1: 
					printf("err: fork\n");
					return 0;

			case 0:
					idata *= 3;
					istack *= 3;
					break;

			default:
					sleep(3);
					break;
		}   

		printf("PID=%ld %s idata=%d istack=%d\n", (long)getpid(),
						(childPid == 0) ? "child " : "parent ", idata, istack);

		exit(EXIT_SUCCESS);
	}

运行结果为

	MISlike@10:56:~/process $ ./t_fork 
	PID=5566 child  idata=333 istack=666
	PID=5565 parent  idata=111 istack=222

无论是数据段还是堆栈段均完成了复制。

  • vfork
	/**********************************************************************

		> File Name: t_vfork.c

		> Author: 0nism

		> Email: fd98shadow@sina.com

		> Created Time: Sun 14 Oct 2018 11:21:22 PM CST

	***********************************************************************/

	#include <unistd.h>
	#include <stdio.h>
	#include <stdlib.h>

	int main(int argc, char **argv)
	{
		int istack = 222;

		switch (vfork())
		{   
			case -1: 
					printf("err: vfork\n");
					return 0;

			case 0:                 //  子进程优先执行,在父进程的虚拟地址空间中
					sleep(3);       //  即使休眠一段时间,父进程仍然不会先执行

					write(STDOUT_FILENO, "Child excuting\n", 16);
					istack *= 3;    //  这个变化将会被父进程知晓
					_exit(EXIT_SUCCESS);

			default:                //  父进程被锁住直到子进程消亡
					write(STDOUT_FILENO, "Parent excuting\n", 16);
					printf("istack = %d\n", istack);
					_exit(EXIT_SUCCESS);

		}   
	}

运行结果如下

Child excuting
Parent excuting
istack = 666

可见子进程操作影响到了父进程,且此时父进程被阻塞,知道子进程消亡或者执行excu()。

posted on 2018-10-15 11:04 0nism 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/0nism/p/9789862.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值