请解释exec()函数及其系列 [英] Please explain exec() function and its family

查看:88
本文介绍了请解释exec()函数及其系列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是什么执行exec()函数及其家人吗?为什么要使用此功能以及如何进行工作?

What is this exec() function and its family? Why this function is used and how it does its work?

请谁能解释这些功能。

推荐答案

简单地说,在UNIX中,你的流程和程序的概念。一个进程是什么,其中一个程序执行。

Simplistically, in UNIX, you have the concept of processes and programs. A process is something in which a program executes.

Unix的执行模式背后的简单的想法是,有两个操作就可以做的。

The simple idea behind the UNIX "execution model" is that there are two operations you can do.

首先是叉(),它会创建一个包含当前程序的副本,包括它的状态一个全新的过程。有这让他们找出哪些是家长,哪些是孩子的过程之间有一些差别。

The first is to fork(), which creates a brand new process containing a duplicate of the current program, including its state. There are a few differences between the processes which allow them to figure out which is the parent and which is the child.

二是执行exec(),这在目前的进程,一个全新的节目替换节目。

The second is to exec(), which replaces the program in the current process with a brand new program.

来自这两个简单的操作,整个UNIX执行模型可以构造。

From those two simple operations, the entire UNIX execution model can be constructed.

要更多细节添加到上面:

To add some more detail to the above:

使用叉()执行exec()的体现了UNIX的精神,因为它提供了一个非常简单的方式开始新进程。

The use of fork() and exec() exemplifies the spirit of UNIX in that it provides a very simple way to start new processes.

叉()调用使当前进程的近重复,相同的几乎每个方式(不是的所有的被复制,为例如,在一些实现中的资源限制,但这个想法是创造尽可能接近的副本作为可能的话)。一个进程调用叉()而两个进程从它返回 - 听起来很离奇,但它真的很优雅。

The fork() call makes a near duplicate of the current process, identical in almost every way (not everything is copied over, for example, resource limits in some implementations, but the idea is to create as close a copy as possible). One process calls fork() while two processes return from it - sounds bizarre but it's really quite elegant

新的工艺(称为子)得到一个不同的进程ID(PID),并有老工艺的将PID(父)作为其父PID(PPID)。

The new process (called the child) gets a different process ID (PID) and has the the PID of the old process (the parent) as its parent PID (PPID).

由于这两个进程正在运行完全相同的code,他们需要的是能够分辨哪个是哪个了 - 叉()提供该信息 - 孩子变0,家长获取孩子的PID(如叉()失败,没有任何儿童被创建和家长得到一个错误code)。这样,父母都知道孩子的PID,可以与它沟通,杀死它,等它等(孩子可以始终以 getppid()的调用)。

Because the two processes are now running exactly the same code, they need to be able to tell which is which - the return code of fork() provides this information - the child gets 0, the parent gets the PID of the child (if the fork() fails, no child is created and the parent gets an error code). That way, the parent knows the PID of the child and can communicate with it, kill it, wait for it and so on (the child can always find its parent process with a call to getppid()).

执行exec()调用替换过程中的整个当前内容的新方案。这将程序加载到当前进程空间,并从入口点运行它。

The exec() call replaces the entire current contents of the process with a new program. It loads the program into the current process space and runs it from the entry point.

因此​​,叉()执行exec()通常按顺序用于获取运行的一个新程序当前进程的孩子。贝壳通常做到这一点,只要你尝试运行像程序找到 - 壳叉,那么孩子加载找到程序装入内存,建立所有命令行参数,标准I / O等等。

So, fork() and exec() are often used in sequence to get a new program running as a child of a current process. Shells typically do this whenever you try to run a program like find - the shell forks, then the child loads the find program into memory, setting up all command line arguments, standard I/O and so forth.

但他们并不需要一起使用。这是完全可以接受的程序来调用叉()没有跟着执行exec()如果,例如,程序包含父母和孩子code(你需要小心你做什么,每个实现可能会有限制)。这是用了很多(现在仍然是)为守护它只是一个监听TCP端口和叉本身的副本,而父追溯到听来处理特定请求。对于这种情况,该程序包含父的的孩子code。

But they're not required to be used together. It's perfectly acceptable for a program to call fork() without a following exec() if, for example, the program contains both parent and child code (you need to be careful what you do, each implementation may have restrictions). This was used quite a lot (and still is) for daemons which simply listen on a TCP port and fork a copy of themselves to process a specific request while the parent goes back to listening. For this situation, the program contains both the parent and the child code.

同样,知道他们是成品,只是想运行其他程序不需要叉() EXEC(程序) 然后等待()/ waitpid函数()的孩子。他们可以直接加载到孩子的当前进程空间执行exec()

Similarly, programs that know they're finished and just want to run another program don't need to fork(), exec() and then wait()/waitpid() for the child. They can just load the child directly into their current process space with exec().

一些UNIX实现具有优化叉()它使用他们所谓的写入时复制。这是为了拖延这一进程空间复制在叉一招()直到程序试图改变的东西在这个空间。这是只使用叉(),而不是 EXEC()这些程序非常有用,因为它们不必复制整个处理空间。在Linux下,叉()才有),页表的副本和新的任务结构, EXEC(将做分离两个过程的记忆繁重的工作。

Some UNIX implementations have an optimized fork() which uses what they call copy-on-write. This is a trick to delay the copying of the process space in fork() until the program attempts to change something in that space. This is useful for those programs using only fork() and not exec() in that they don't have to copy an entire process space. Under Linux, fork() only makes a copy of the page tables and a new task structure, exec() will do the grunt work of "separating" the memory of the two processes.

如果在 EXEC 的称为继(这是大多发生),导致要处理空间的写入,然后将其复制为子过程

If the exec is called following fork (and this is what happens mostly), that causes a write to the process space and it is then copied for the child process.

Linux也有一个的vfork(),更加优化,这两个进程之间共享只是的所有的。正因为如此,有什么孩子可以做一定的限制,并且父暂停,直到孩子叫执行exec() _exit()

Linux also has a vfork(), even more optimised, which shares just about everything between the two processes. Because of that, there are certain restrictions in what the child can do, and the parent halts until the child calls exec() or _exit().

父已被停止(和子不允许从当前函数返回),因为这两个过程,即使共享相同的堆栈。这是 fork()的经典用例会更有效紧接着执行exec()

The parent has to be stopped (and the child is not permitted to return from the current function) since the two processes even share the same stack. This is slightly more efficient for the classic use case of fork() followed immediately by exec().

请注意,有 EXEC 电话(的全家 EXECL execle 的execve 等),但 EXEC 上下文这里是指任何人。

Note that there is a whole family of exec calls (execl, execle, execve and so on) but exec in context here means any of them.

下图说明,其中庆典外壳是用来列出目录具有典型的叉/ EXEC 操作在 LS 命令:

The following diagram illustrates the typical fork/exec operation where the bash shell is used to list a directory with the ls command:

+--------+
| pid=7  |
| ppid=4 |
| bash   |
+--------+
    |
    | calls fork
    V
+--------+             +--------+
| pid=7  |    forks    | pid=22 |
| ppid=4 | ----------> | ppid=7 |
| bash   |             | bash   |
+--------+             +--------+
    |                      |
    | waits for pid 22     | calls exec to run ls
    |                      V
    |                  +--------+
    |                  | pid=22 |
    |                  | ppid=7 |
    |                  | ls     |
    V                  +--------+
+--------+                 |
| pid=7  |                 | exits
| ppid=4 | <---------------+
| bash   |
+--------+
    |
    | continues
    V

这篇关于请解释exec()函数及其系列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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