您的位置:首页 > 运维架构 > Linux

Linux 下 fork, vfork,和clone的区别

2017-06-06 13:13 447 查看
对操作系统而言,进程是一个指令执行流及其执行环境的统称,这里的执行环境是一个系统资源的集合,所有涉及到的资源在Linux中被抽象成各种数据:进程控制块、虚存空间、文件系统,文件I/O、信号处理函数等。因此,对操作系统来说,创建一个进程的过程就是这些数据对象的创建过程。

Linux内核通常把进程也叫做任务,一般来说,进程具有以下四个特点,且缺一不可:

(1)一段代码块供其执行

(2)专用系统堆栈空间

(3)进程控制块

(4)独立的存储空间

我们通常将缺少第四条的称为线程,线程是进程基础上进一步抽象的产物。线程的创建、管理以及销毁等过程我们将在后续的文章中进行说明。
在Linux系统中,进程的创建主要有由操作系统创建,和由父进程创建两种方式。严格来说,Linux系统中的用户进程不能直接被创建出来,只能通过特定的API从某个进程中复制出来,复制进程的API包括三种:fork、vfork、clone。他们作为系统调用,分别调用了sys_fork、sys_vfork、sys_clone,最终他们都调用了do_fork函数,三者的差别在于相应的准备工作和参数的传递不同。

系统调用      
描述
fork
fork创造的子进程是父进程的完整副本,复制了父亲进程的资源(父进程的进程地址空间),包括内存的task_struct内容,父子进程运行的先后顺序是随机的
vfork
vfork的特点是创建的子进程与父进程共享数据段,而且由vfork()创建的子进程将先于父进程运行
clone
一般Linux中创建线程一般使用POSIX提供的pthread库,但实际上linux也提供了创建线程的系统调用,也就是clone,此外,clone还具有其他特殊功能
fork 创建的子进程复制了父亲进程的资源(copy-on-write技术),包括内存的内容task_struct内容(即父子进程的pid不同)。当父进程使用系统调用fork()创建一个子进程时,子进程的代码段、数据段、堆栈都是指向父进程的物理空间,也就是说,两者的虚拟空间不同,但其对应的物理空间是同一个。

vfork创建的子进程共享父进程的空间(包括虚拟空间与物理空间),同时vfork返回后,直接使用父进程的内存和数据,也就是说若子进程修改或破坏了父进程的数据结构,则会造成返回失败或者引起系统崩溃等,因此在调用vfork时,若发生子进程修改了父进程数据结构的话,则不能调用exit进行返回操作。

clone()可以说是fork的升级版,它不仅可以创建进程或者线程,甚至可以有选择的继承父进程的内存、将创建出来的进程变成父进程的兄弟进程等等。clone的原型为:

int clone(int (fn)(void ), void*child_stack, int flags, void *arg);

fn是函数指针;child_stack是子进程分配系统堆栈空间,flags为子进程将从父进程继承哪些资源,arg则是传给子进程的参数。flag标志常见的选项和含义如下表所示:

标志
含义
CLONE_PARENT
创建的子进程的父进程是调用者的父进程,新进程与创建它的进程成了“兄弟”而不是“父子”
CLONE_FS
子进程与父进程共享相同的文件系统,包括root、当前目录、umask
CLONE_FILES
子进程与父进程共享相同的文件描述符(file descriptor)表
CLONE_NEWNS
在新的namespace启动子进程,namespace描述了进程的文件hierarchy
CLONE_SIGHAND
子进程与父进程共享相同的信号处理(signal handler)表
CLONE_PTRACE
若父进程被trace,子进程也被trace
CLONE_VFORK
父进程被挂起,直至子进程释放虚拟内存资源
CLONE_VM
子进程与父进程运行于相同的内存空间
CLONE_PID
子进程在创建时PID与父进程一致
CLONE_THREAD
Linux 2.4中增加以支持POSIX线程标准,子进程与父进程共享相同的线程群
通过上面的分析,我们不难发现,在执行fork时clone_flag= SIGCHLD;在vfork时clone_flag= CLONE_VM | CLONE_VFORK | SIGCHLD;而在clone中,clone_flag一般由用户给出。

以上为学习Linux进程以及进程管理时的一点心得,其中也参考了一些大神的技术博客,在此表示感谢,文章内容若有错误或不足,还请各位大神指正,谢谢!
文章若有侵权行为,请及时联系作者。谢谢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Linux fork vfork clone api