通过fork、vfork和clone创建进程


一、Fork
应用程序可以通过fork系统调用创建一个和调用fork进程一样的子进程,该子进程继承了父进程(也就是调用fork的那个进程)的所有的资源,除了:
1、进程ID
2、父进程ID
3、文件锁没有继承
4、Pending signal没有继承
由于linux内核使用了COW(copy-on-write)技术,因此fork的开销不算特别大,主要是复制父进程页表的开销。

二、Vfork
Vfork和fork是类似的,除了下面两点:
1、阻塞父进程
2、不复制父进程的页表
之所以会有vfork这样的创建进程的方法,其主要原因是由于很可能父进程在fork之后会调用exec函数,如果这样,fork所做的努力都白费了。在引入了COW技术后,fork开销已经不大,因此vfork的意义也不是非常的明显。
之所以vfork要阻塞父进程是因为vfork后父子进程使用的是完全相同的mm, 也就是说使用的是完全相同的虚拟内存空间, 包括栈也相同。所以两个进程不能同时运行, 否则栈就乱掉了。所以vfork后, 父进程是阻塞的,直到调用了exec系列函数或者exit函数后。这时候,子进程的mm(old_mm)需要释放掉,不再与父进程共用了,这时候就可以解除父进程的阻塞状态。
Vfork本身的机制就是有问题的,考虑exec调用失败的情况,父进程将被挂起不确定时间,直到子进程决定自己该怎么做或者直到子进程退出。因此不建议使用vfork。

三、Clone
Linux内核提供的clone的系统调用接口主要用于线程的创建,这个接口提供了更多的灵活性,可以让用户指定父进程和子进程(也就是创建的进程)共享的内容。其实通过传递不同的参数,clone接口可以实现fork和vfork的功能。
用户可以控制的flag包括:
1、CLONE_PARENT。一般而言,调用进程是被创建进程的父进程,不过设定该标识则创建的子进程的父进程是调用者的父进程,新进程与创建它的进程成了“兄弟”而不是“父子”
2、CLONE_FS。设定该标识则子进程与父进程共享相同的文件系统,包括root目录、当前目录、umask等信息。
3、CLONE_FILES。设定该标识则子进程与父进程共享相同的文件描述符(file descriptor)表
4、CLONE_NEWNS。设定该标识则在新的namespace启动子进程。namespace描述了进程可以看到的文件树。当在新的namespace启动子进程后,父子进程看到的是不同的文件树,因此一个进程的mount或者umount的动作不会影响另外一个进程。
5、CLONE_SIGHAND。设定该标识则子进程与父进程共享相同的信号处理(signal handler)表。虽然父子进程的signal handler是共享的,不过signal mask和signal pending的控制是分开的,父子进程可以各自mask自己的信号。
6、CLONE_PTRACE。设定该标识则若父进程被trace,子进程也被trace。
7、CLONE_VFORK。参考上面关于vfork的描述。
8、CLONE_VM。设定该标识则子进程与父进程运行于相同的内存空间。
9、CLONE_THREAD。设定该标识则子进程与父进程在一个线程组中。否则会创建一个新的线程组,子进程的thread ID(task struct中的pid域)就是新的线程组的ID,而该线程是该线程组的leader。当用fork创建一个进程的时候不会携带该flag,因为父进程和子进程不会是同一个线程组(task->tgid = task->pid)。而在线程库中,会需要携带该flag,因为所有的线程属于同一个线程组,因此tgid会跟随创建task的tgid(task ->tgid = current->tgid)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值