为什么exec()函数系列在exec()之后不执行代码?

手册页说“exec()系列函数用新的过程映像替换当前过程映像。” 但我不太明白“用新的过程图像替换当前过程图像”的含义。 例如,如果exec成功,则不会达到perror

execl("/bin/ls", /* Remaining items sent to ls*/ "/bin/ls", ".", (char *) NULL); perror("exec failed"); 

正确。 如果exec有效,则不会调用perror ,因为对perror的调用不再存在。

我发现在教育这些概念的新手时,将UNIX执行模型视为由流程, 程序程序实例组成,有时会更容易

程序是可执行文件,例如/bin/ls/sbin/fdisk (请注意,这不包括bash或Python脚本之类的东西,因为在这种情况下,实际的可执行文件将是bashpython解释器,而不是脚本) 。

程序实例是已加载到内存中并基本上正在运行的程序。 虽然只有一个程序像/bin/ls ,但是如果你和我同时运行它,那么在任何给定的时间可能会有多个实例运行。

“加载到内存中”这个短语是流程进入图片的地方。 进程只是程序实例可以运行的“容器”。

因此,当您fork一个进程时,最终会有两个不同的进程,但它们仍然每个运行同一程序的不同实例。 fork调用通常被称为一个进程调用但两个进程从中返回的调用。

同样, exec不会对进程本身产生影响,但丢弃该进程中的当前程序实例并启动所请求程序的新实例。

成功的exec调用中的丢弃是指示后面的代码(在这种情况下为perror )将不会被调用。

这意味着您当前的流程将成为新流程而非其流程。 你停止做你正在做的事情并开始做,真的存在,而不是其他事情,永远不会重新成为曾经的过程。

然而,不是开始一个全新的过程,而是当前的pid和环境成为新的过程。 这让你在执行exec之前按照新进程需要的方式设置东西

你是对的。 除非execl失败,否则不会调用perror。 exec函数是在POSIX兼容的OS中启动新进程的手段(通常与fork调用结合使用)。 也许一个例子会有所帮助。 假设您的程序称为programX,正在运行。 然后它调用一个exec函数,就像你上面的那个。 programX将不再作为正在运行的进程存在。 相反,ls将会运行。 它将具有与programX相同的精确PID,但是否则几乎是一个全新的过程。