我们编写程序的时候会用到fork 、vfork 、clone等函数来创建一个子进程,但是,这些函数是怎么做到创建一个子进程的呢,底层是怎样实现的呢?我们通过分析内核代码来了解这些。
进程创建
查看 相关的内核代码 ,可以看到如下程序段
SYSCALL_DEFINE0(fork)
{
return do_fork(SIGCHLD, 0, 0, NULL, NULL);
}
....
SYSCALL_DEFINE0(vfork)
{
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, 0, NULL, NULL);
}
...
SYSCALL_DEFINE5(clone, unsigned long, clone_flags,
unsigned long, newsp, int __user *, parent_tidptr,
int __user *, child_tidptr, int, tls_val)
{
return do_fork(clone_flags, newsp, 0, parent_tidptr,
child_tidptr);
}
...
这里只提取出关键信息,可以看到,三个函数都调用了do_fork()来完成。那么既然实际上都是调用一个过程,为什么要有fork,vfork,clone这么多不同的函数呢?实际上这是为了不同的场景需要而设计的,文章结尾部分是查阅资料总结这三个函数的区别,现在的重点是看内核是怎么创建新进程的,所以我们先来看do_fork代码,代码中关键地方做了注释。
long do_fork(unsigned long clone_flags, unsigned long stack_start,
unsigned long stack_size, int __user *parent_tidptr,