execv() 和 fork() 的时间浪费 [英] Time waste of execv() and fork()

查看:11
本文介绍了execv() 和 fork() 的时间浪费的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在学习 fork()execv(),我对组合的效率有疑问.

I am currently learning about fork() and execv() and I had a question regarding the efficiency of the combination.

我看到了以下标准代码:

I was shown the following standard code:

pid = fork();
if(pid < 0){
    //handle fork error
}
else if (pid == 0){
    execv("son_prog", argv_son);
//do father code

我知道 fork() 克隆整个进程(复制整个堆等)并且 execv() 用新的地址空间替换当前地址空间程序.考虑到这一点,使用这种组合是否会变得非常低效?我们正在复制一个进程的整个地址空间,然后立即覆盖它.

I know that fork() clones the entire process (copying the entire heap, etc) and that execv() replaces the current address space with that of the new program. With this in mind, doesn't it make it very inefficient to use this combination? We are copying the entire address space of a process and then immediately overwrite it.

所以我的问题:
使用这种组合(而不是其他一些解决方案)实现的优势是什么,使人们仍然使用它,即使我们有浪费?

So my question:
What is the advantage that is achieved by using this combo (instead of some other solution) that makes people still use this, even though we have waste?

推荐答案

使用这种组合(而不是其他一些解决方案)实现的优势是什么,即使我们有浪费,人们仍然使用它?

What is the advantage that is achieved by using this combo (instead of some other solution) that makes people still use this even though we have waste?

您必须以某种方式创建一个新流程.用户空间程序实现这一点的方法很少.POSIX曾经有vfork() alognside fork(),有些系统可能有自己的机制,比如Linux特有的clone(),但自 2008 年以来,POSIX 仅指定 fork()posix_spawn() 系列.fork + exec 路线更传统,易于理解,并且几乎没有缺点(见下文).posix_spawn 系列被设计为特殊用途 替代品,用于在 fork() 存在困难的上下文中使用;您可以在其规范的基本原理"部分找到详细信息.

You have to create a new process somehow. There are very few ways for a userspace program to accomplish that. POSIX used to have vfork() alognside fork(), and some systems may have their own mechanisms, such as Linux-specific clone(), but since 2008, POSIX specifies only fork() and the posix_spawn() family. The fork + exec route is more traditional, is well understood, and has few drawbacks (see below). The posix_spawn family is designed as a special purpose substitute for use in contexts that present difficulties for fork(); you can find details in the "Rationale" section of its specification.

vfork() 的 Linux 手册页摘录可能很有启发性:

This excerpt from the Linux man page for vfork() may be illuminating:

在Linux下,fork(2)是使用copy-on-write页面实现的,所以fork(2)唯一的惩罚就是时间复制父页表和为子页创建独特的任务结构所需的内存.然而,在过去的糟糕日子里,fork(2) 需要制作调用者数据空间的完整副本,这通常是不必要的,因为通常紧接着 exec(3)已经完成了.因此,为了提高效率,BSD 引入了 vfork() 系统调用,它并没有完全复制父进程的地址空间,而是借用了父进程的内存和控制线程,直到调用 execve(2) 或发生退出.父进程在子进程使用其资源时被挂起.vfork() 的使用很棘手:例如,不修改父进程中的数据取决于知道哪些变量保存在寄存器中.

Under Linux, fork(2) is implemented using copy-on-write pages, so the only penalty incurred by fork(2) is the time and memory required to duplicate the parent’s page tables, and to create a unique task structure for the child. However, in the bad old days a fork(2) would require making a complete copy of the caller’s data space, often needlessly, since usually immediately afterwards an exec(3) is done. Thus, for greater efficiency, BSD introduced the vfork() system call, which did not fully copy the address space of the parent process, but borrowed the parent’s memory and thread of control until a call to execve(2) or an exit occurred. The parent process was suspended while the child was using its resources. The use of vfork() was tricky: for example, not modifying data in the parent process depended on knowing which variables are held in a register.

(已添加重点)

因此,您对浪费的担忧对于现代系统(不限于 Linux)来说是没有根据的,但它确实是历史上的一个问题,并且确实有一些机制可以避免它.如今,这些机制中的大多数都已过时.

Thus, your concern about waste is not well-founded for modern systems (not limited to Linux), but it was indeed an issue historically, and there were indeed mechanisms designed to avoid it. These days, most of those mechanisms are obsolete.

这篇关于execv() 和 fork() 的时间浪费的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆