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

查看:203
本文介绍了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.

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

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

在Linux下,fork(2)是使用写时复制页实现的,因此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天全站免登陆