Linux 下 fork, vfork,和clone的区别

对操作系统而言,进程是一个指令执行流及其执行环境的统称,这里的执行环境是一个系统资源的集合,所有涉及到的资源在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进程以及进程管理时的一点心得,其中也参考了一些大神的技术博客,在此表示感谢,文章内容若有错误或不足,还请各位大神指正,谢谢!

文章若有侵权行为,请及时联系作者。谢谢!


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值