为什么在线程之间切换比在进程之间切换并在它们之间共享数据更快?例如,在 ubuntu 上运行的 apache web 服务器可以使用 Prefork MPM(生成多个子进程)或 Worker MPM(为单个进程创建多个线程)。
答案1
快速、不完整的解释:
在线程切换中,需要保存/加载的上下文要少得多。具体来说,内存是共享的。内核不必对脏页进行任何页面移出,VM 技巧会将所有内存拉入新进程(尽管可能需要拉入某些特定页面)。内核中还有其他特定于进程的数据结构(例如,打开的文件描述符表),不需要换出。
作为副作用,您也更有可能在此时使用处理器缓存中的内容。新进程可能需要启动冷缓存。
是的,有一些工具可以在进程之间共享内存(IPC 共享内存、管道),但没有一个像进程中的公共内存那样干净/简单。您无法像使用 realloc() 等那样增加共享内存块。除了共享内存之外的任何东西都意味着您需要多个数据结构副本,每个进程一个,并使用技巧根据需要复制更改。
具体来说,Apache 有多种适用于不同操作系统的模型。原始模型是预分叉的,以一些重量级的进程切换为代价,提供进程隔离。这在它首次编写时很常见的 UNIX 上工作得很好,其中一些 UNIX 根本没有线程。Windows 在多进程方面表现非常糟糕,以至于 Apache有进行线程处理 - Windows 上的进程(至少在 apache 1.2/2.0 时代)太重了。Linux 的进程非常轻量,切换时间接近线程切换时间,因此通常处于 Fork 之前的状态。Solaris 有一个复杂的线程“LWP”模型,在混合线程/fork 模型中表现最佳。
答案2
我认为如果你读过这个 StackOverflow 链接这里你将会明白为什么在线程之间切换比在进程之间切换更快。