gpt4 book ai didi

linux - 为什么 fork() 以它的方式工作

转载 作者:IT老高 更新时间:2023-10-28 12:39:50 26 4
gpt4 key购买 nike

所以,我使用了 fork() 并且知道它的作用。作为一个初学者,我很害怕它(我仍然不完全理解它)。 fork() 的一般描述你可以在网上找到,它复制当前进程并分配不同的 PID,父 PID 和进程将有不同的地址空间。一切都很好,但是,鉴于此功能描述,初学者会想知道“为什么这个功能如此重要......为什么我要复制我的流程?”。所以我确实想知道,最终我发现这就是您可以通过 execve() 系列从当前进程中调用其他进程的方式。

我仍然不明白为什么你必须这样做?最合乎逻辑的事情是拥有一个可以像

一样调用的函数
create_process("executable_path+name",params..., more params); 

这将产生一个新进程并在 main() 的开头开始运行它并返回新的 PID。

让我感到困扰的是 fork/execve 解决方案正在做可能不需要的工作。如果我的进程正在使用大量内存怎么办?内核是否复制我的页表等。我确信它并没有真正分配真正的内存,除非我接触过它。另外,如果我有线程会发生什么?在我看来,它太乱了。

几乎所有关于 fork 做什么的描述,说它只是复制进程,新进程在 fork() 调用之后开始运行。这确实是发生的事情,但为什么会这样,为什么 fork/execve 是生成新进程的唯一方法,以及从当前进程创建新进程的最通用的 unix 方法是什么?还有其他更有效的方法来生成进程吗?** 不需要复制更多内存。

This线程讨论了同样的问题,但我发现它不太令人满意:

谢谢。

最佳答案

这是由于历史原因。如 https://www.bell-labs.com/usr/dmr/www/hist.html 中所述,很早的Unix确实没有fork()也没有exec*(),shell执行命令的方式是:

  • 进行必要的初始化(打开stdin/stdout)。
  • 读取命令行。
  • 打开命令,加载一些引导代码并跳转到它。
  • 引导代码读取打开的命令,(覆盖 shell 的内存)并跳转到它。
  • 一旦命令结束,它将调用 exit(),然后通过重新加载 shell(覆盖命令的内存)并跳转到它,返回到第 1 步来工作。

从那里,fork() 是一个简单的添加(27 条装配线),可重复使用其余代码。

在 Unix 开发的那个阶段,执行命令变成了:

  • 读取命令行。
  • fork() 一个子进程,并等待它(通过向它发送消息)。
  • 子进程加载命令(覆盖子内存),并跳转到它。
  • 一旦命令结束,它会调用 exit(),这现在更简单了。它只是清理了它的进程入口,并放弃了控制。

最初,fork() 没有在写入时进行复制。由于这使得 fork() 变得昂贵,并且 fork() 经常被用来生成新进程(所以经常紧随其后的是 exec*()),出现了fork()的优化版本:vfork(),父子共享内存。在那些 vfork() 的实现中,父级将被挂起,直到子级 exec*()'ed 或 _exit()'ed,因此放弃 parent 的内存。后来,fork() 被优化为在写入时进行复制,仅在内存页开始在父子节点之间出现差异时复制内存页。 vfork() 后来发现对 !MMU 系统的端口重新产生了兴趣(例如:如果你有一个 ADSL 路由器,它可能在 !MMU MIPS CPU 上运行 Linux),它无法进行 COW 优化,而且无法有效地支持 fork() 的进程。

fork() 中效率低下的其他原因是它最初复制了父级的地址空间(和页表),这可能会使从大型程序运行短程序相对较慢,或者可能使操作系统拒绝 fork() 认为可能没有足够的内存(要解决这个问题,您可以增加交换空间,或更改操作系统的内存过度使用设置)。作为轶事,Java 7 使用 vfork()/posix_spawn() 来避免这些问题。

另一方面,fork() 使得创建同一进程的多个实例非常高效:例如:一个 Web 服务器可能有多个相同的进程为不同的客户端服务。其他平台偏爱线程,因为生成不同进程的成本远高于复制当前进程的成本,而复制当前进程的成本可能仅比生成新线程的成本高一点。这是不幸的,因为共享所有线程是错误的磁铁。

关于linux - 为什么 fork() 以它的方式工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8292217/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com