博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux中建立新的进程-fork、vfork、clone解析
阅读量:4212 次
发布时间:2019-05-26

本文共 2112 字,大约阅读时间需要 7 分钟。

1.pid_t fork(void)

asmlinkage int sys_fork(unsigned long r0, unsigned long r1, unsigned long r2,	unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6,	struct pt_regs regs){#ifdef CONFIG_MMU	return do_fork(SIGCHLD, regs.spu, &regs, 0, NULL, NULL);#else	return -EINVAL;#endif /* CONFIG_MMU */}

2.pid_t vfork(void)

/* * This is trivial, and on the face of it looks like it * could equally well be done in user mode. * * Not so, for quite unobvious reasons - register pressure. * In user mode vfork() cannot have a stack frame, and if * done by calling the "clone()" system call directly, you * do not have enough call-clobbered registers to hold all * the information you need. */asmlinkage int sys_vfork(unsigned long r0, unsigned long r1, unsigned long r2,	unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6,	struct pt_regs regs){	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.spu, &regs, 0,			NULL, NULL);}

3.int clone(int (*fn)(void *), void *child_stack, int flags, void *arg)

asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,			 unsigned long parent_tidptr,			 unsigned long child_tidptr,			 unsigned long r4, unsigned long r5, unsigned long r6,			 struct pt_regs regs){	if (!newsp)		newsp = regs.spu;	return do_fork(clone_flags, newsp, &regs, 0,		       (int __user *)parent_tidptr, (int __user *)child_tidptr);}

fork与vfork对比分析

fork 、 vfork 、clone函数最终都是调用do_fork,只是传递的参数不同,重点在于clone_flags参数的不同。fork传递的只有SIGCHLD, vfork传递的是CLONE_VFORK | CLONE_VM | SIGLCHLD。而clone函数可操作性比较大,可以自主设置clone_flags。

1.vfork保证子进程先运行,在它调用exec或exit之后父进程才可能被调度运行。如果在调用这两个函数之前子进程依赖于父进程的进一步动作,则会导致死锁。

2.fork要拷贝父进程的进程环境;而vfork则不需要完全拷贝父进程的进程环境,在子进程没有调用exec和exit之前,子进程与父进程共享进程环境(观察源码发现主要是CLONE_VM,共享用户虚拟地址空间),此时父进程阻塞等待。

为什么会有vfork呢?

因为以前的fork当它创建一个子进程时,将会创建一个新的地址空间,并且拷贝父进程的资源,然后将会有两种行为:

1.执行从父进程那里拷贝过来的代码段

2.调用一个exec执行一个新的代码段

当进程调用exec函数时,一个新程序替换了当前进程的正文,数据,堆和栈段。这样,前面的拷贝工作就是白费力气了,这种情况下,聪明的人就想出了vfork。vfork并不复制父进程的进程环境,子进程在父进程的地址空间中运行,所以子进程不能进行写操作,并且在儿子“霸占”着老子的房子时候,要委屈老子一下了,让他在外面歇着(阻塞),一旦儿子执行了exec或者exit后,相当于儿子买了自己的房子了,这时候就相当于分家了。

因此,如果创建子进程是为了调用exec执行一个新的程序的时候,就应该使用vfork

转载地址:http://ciumi.baihongyu.com/

你可能感兴趣的文章
【IOS游戏开发】之IPA破解原理
查看>>
【一天一道LeetCode】#45. Jump Game II
查看>>
【一天一道LeetCode】#46. Permutations
查看>>
【一天一道LeetCode】#47. Permutations II
查看>>
【一天一道LeetCode】#56. Merge Intervals
查看>>
【一天一道LeetCode】#58. Length of Last Word
查看>>
【一天一道LeetCode】#59. Spiral Matrix II
查看>>
【一天一道LeetCode】#30. Substring with Concatenation of All Words
查看>>
【一天一道LeetCode】#60. Permutation Sequence.
查看>>
【一天一道LeetCode】#113. Path Sum II
查看>>
【一天一道LeetCode】#114. Flatten Binary Tree to Linked List
查看>>
【unix网络编程第三版】阅读笔记(二):套接字编程简介
查看>>
【一天一道LeetCode】#115. Distinct Subsequences
查看>>
【一天一道LeetCode】#116. Populating Next Right Pointers in Each Node
查看>>
【一天一道LeetCode】#117. Populating Next Right Pointers in Each Node II
查看>>
【一天一道LeetCode】#118. Pascal's Triangle
查看>>
同步与异步的区别
查看>>
IT行业--简历模板及就业秘籍
查看>>
JNI简介及实例
查看>>
JAVA实现文件树
查看>>