新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > Linux中的fork与exec系列函数分析

Linux中的fork与exec系列函数分析

作者:嵌入式经验分享 时间:2025-08-06 来源:今日头条 收藏

fork 和 exec 的使用体现了 UNIX 的精髓,它提供了一种非常简单的方式来启动新的任务。注意这里“任务”一词的使用,我刻意避免使用“进程”或“程序”这两个术语:

进程是“执行引擎”,是操作系统中能够运行程序的实体;

程序是用于执行相同任务的特定代码片段。

你可以在不同的进程中运行同一个程序(例如交互式 shell)。

fork()的功能

考虑到这一点,fork 调用基本上会复制当前进程,几乎在各个方面都完全相同。并非所有内容都会被复制(例如,某些实现中的资源限制),但其目的是创建尽可能接近的副本。

fork将创建新进程(也叫子进程),子进程会获得不同的进程 ID (PID),并将创建它的进程(父进程)的 PID 作为其父进程 PID (PPID)。虽然两个进程运行的是同一个程序,但是它们可以通过 fork 的返回值来区分——子进程返回 0,而父进程返回子进程的 PID。当然,这一切都建立在 fork 调用成功的前提上——如果失败,则不会创建子进程,父进程会返回错误码。

exec()的功能

exec 调用本质上是用一个新程序替换进程中整个当前程序的方法。它会将新程序加载到当前进程空间,并从入口点运行。

因此,fork 和 exec 通常按顺序使用,以使新程序作为当前进程的子进程运行。每当你尝试运行类似 find 的程序时,Shell 通常会执行此操作——Shell 会 fork,然后子进程将 find 程序加载到内存中,设置所有命令行参数、标准 I/O 等等。

一些 UNIX 实现对 fork 进行了优化,使用了所谓的“写时复制”机制。这是一种技巧,可以延迟 fork 过程中对进程空间的复制,直到程序尝试更改该空间中的某些内容。这对于只使用 fork 而不使用 exec 的程序非常有用,因为它们不必复制整个进程空间。

exec 调用有很多种(execl、execle、execve 等等),但此处上下文中的 exec 指的是其中任何一个。

实例演示

下图演示了典型的 fork/exec 操作,其中使用 bash shell 的 ls 命令列出目录:

+--------+| 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    |   to finish          V
   |                  +--------+    |                  | pid=22 |
   |                  | ppid=7 |
   |                  | ls     |
   V                  +--------+
+--------+                 || pid=7  |                 | exits
| ppid=4 | <---------------+
| bash   |
+--------+
   |
   | continues
   V



关键词: Linux

评论


相关推荐

技术专区

关闭