fork/vfork/clone的区别

6 篇文章 0 订阅

  Linux进程所需具备的4个要素:

  1.进程控制块:即task_struct结构,存储进程状态和所占用的资源。基于该结构,进程才能成为内核调度的基本单位,接受调度。

  2.系统堆栈空间:进程专属空间,用于存放各种私有数据以及堆栈(含用户态堆栈和内核态堆栈)。

  3.进程代码块:只读,所以,可与其他进程共享。

  4.独立的用户空间,含堆、BSS、初始化非零数据区等

  如果不具有第4个要素,则称其为”线程“。如果完全没有用户空间,称为“内核线程”。

 

  创建子进程的系统调用有3种fork、vfork、clone。这三种函数通过系统调用表映射到sys_fork(), sys_vfork(), sys_conle(),再在这三个函数中去调用do_fork()去做具体的创建进程工作。调用do_fork时只是填写的参数不同而已。区别如下:

  fork的实现:   do_fork(SIGCHLD,...)
  clone
的实现:  do_fork(CLONE_VM|CLONE_FS|CLONE_FILES| SIGCHLD,...)
  vfork
的实现:    do_fork(CLONE_VFORK|CLONE_VM| SIGCHLD,...)


FLAG含义如下:

SIGCHLD所创建的(子)进程终止时,应该发送SIGCHLD信号给父进程

CLONE_VM:子进程与父进程运行于相同的内存空间

CLONE_FS:子进程与父进程共享相同的文件系统,包括root、当前目录、umask

CLONE_FILES:子进程与父进程共享相同的文件描述符(filedescriptor)表

CLONE_VFORK:父进程被挂起,直至子进程释放虚拟内存资源


以下总结区别:

  •  fork

fork创造的子进程复制了父进程资源,包括内存及进程描述符的内容。为避免无意义的内存页面复制,Linux采用的COWCopyOn Write, 写时复制)来延迟实际页面的复制,只有父进程或子进程对页面进行写时,才分配并复制页面。所以,刚执行fork时的代价仅仅是创建子进程的页表结构和创建一个task_struct结构。

  • vfork

由于很多情况下,vfork之后,用户的意图并不是继续执行父进程,而是想调用exec来执行其他程序。所以,这为优化这类情况,Linux引入了vforkvforkfork的区别主要体现在两方面:

1)执行vfork时,完全和父进程共享内存,包括堆、BSS、初始化非0数据区等区域。所以,vfork之后对数据的所有修改都会被父进程所见。而fork只是延迟了复制,在修改数据的时间还是需要复制页面。正常使用时,调用vfork之后,应用立即调用exec执行其他程序。

2vfork时,父进程会被阻塞,直到子进程调用了execexit

  • clone

clone()系统调用是fork()的推广形式,它允许新进程指定具体需要与父进程共享哪些元素,如存储空间、文件描述符、信号处理程序等。是否需要阻塞父进程等,所以,比fork更加灵活。

clonefork/vfork的区别主要有以下几点:

1)  fork/vforkPOSIX标准系统调用,而cloneLinux的自定义扩展;

2)  fork/vfork都没有参数,而clone带有参数;

3)  fork是全部复制,vfork是共享内存,而clone是则可以将父进程资源有选择地复制给子进程,而没有复制的数据结构则通过指针的复制让子进程共享,具体要复制哪些资源给子进程,由参数列表中的clone_flags来决定;

4)  clone可以指定子进程的函数体,并可以传递参数给子进程的函数体;

5)  vfork调用中,子进程先运行,父进程挂起,直到子进程调用了exec或exit之后,父子进程的执行次序才不再有限制;clone中由标志CLONE_VFORK来决定子进程在执行时父进程是阻塞还是运行,若没有设置该标志,则父子进程同时运行,设置了该标志,则父进程挂起,直到子进程结束为止。

 

总结:如果想简单,用fork/vfork;如果希望灵活控制或想创建线程、兄弟进程等,则应选择clone

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值