我听说在Windows机器上创建一个新进程比在Linux上创建一个新进程更昂贵。这是真的吗?有人能解释一下为什么它更贵的技术原因,并提供这些原因背后的设计决策的历史原因吗?
发布于 2008-09-07 08:17:13
mweerden: NT从一开始就是为多用户设计的,所以这不是一个真正的理由。然而,您是对的,进程创建在NT上的作用不如在Unix上那么重要,因为与Unix相比,NT更倾向于多线程而不是多处理。
Rob,当使用COW时,fork确实相对便宜,但事实上,fork之后大多是exec。而且exec还必须加载所有图像。因此,讨论fork的性能只是事实的一部分。
在讨论进程创建速度时,区分NT和Windows/Win32可能是个好主意。就NT (即内核本身)而言,我不认为进程创建(NtCreateProcess)和线程创建(NtCreateThread)比普通Unix慢很多。可能还有更多的原因,但我看不出性能差异的主要原因。
但是,如果您查看Win32,您会注意到它为进程创建增加了相当多的开销。首先,它需要通知CSRSS有关进程创建的信息,这涉及到LPC。它至少需要额外加载kernel32,并且在该流程被视为完全成熟的Win32流程之前,它必须执行许多额外的记账工作项。我们不要忘记解析清单所带来的所有额外开销,检查映像是否需要兼容性填充,检查软件限制策略是否适用,等等。
也就是说,我看到除了进程、VA空间和初始线程的原始创建之外,所有这些小事情的总和都在减慢。但正如一开始所说的那样--由于多线程比多任务更受青睐,唯一受到这种额外开销严重影响的软件是移植不佳的Unix软件。尽管当Chrome和IE8等软件突然重新发现多进程的好处并开始频繁地启动和销毁进程时,这种情况发生了变化……
发布于 2008-09-06 21:55:10
Unix有一个' fork‘系统调用,它将当前进程’拆分‘为两个进程,并提供与第一个进程相同的第二个进程(对fork调用的返回取模)。由于新进程的地址空间已经启动并运行,因此这应该比在Windows中调用'CreateProcess‘并让其加载可执行文件映像、相关dll等更便宜。
在分叉的情况下,OS可以对与这两个新进程相关联的存储器页面使用“写入时复制”语义,以确保每个进程都获得它们随后修改的页面的自己的副本。
发布于 2008-09-15 21:43:40
补充JP所说的:大部分开销属于进程的Win32启动。
Windows NT内核实际上支持牛叉。SFU (微软的UNIX环境)使用它们。但是,Win32不支持fork。SFU进程不是Win32进程。SFU与Win32是正交的:它们都是构建在同一内核上的环境子系统。
除了对CSRSS的进程外LPC调用之外,在XP和更高版本中,还存在对应用程序兼容性引擎的进程外调用,以在应用程序兼容性数据库中查找程序。此步骤会产生足够的开销,因此出于性能原因,微软向disable the compatibility engine on WS2003提供了一个组策略选项。
Win32运行时库(kernel32.dll等)此外,在启动时执行大量注册表读取和初始化,这些操作不适用于UNIX、SFU或本机进程。
本机进程(没有环境子系统)的创建速度非常快。SFU在进程创建方面比Win32少得多,因此它的进程创建起来也很快。
2019年更新:添加LXSS:Windows Subsystem for Linux
取代Windows 10的SFU的是LXSS环境子系统。它是100%内核模式,不需要任何Win32继续拥有的进程间通信。这些进程的系统调用直接指向lxss.sys/lxcore.sys,因此fork()或其他创建调用的进程只花费创建者total的1个系统调用。[A data area called the instance] keeps track of all LX processes, threads, and runtime state.
LXSS进程基于本机进程,而不是Win32进程。所有特定于Win32的东西,比如兼容性引擎,根本就没有被使用。
https://stackoverflow.com/questions/47845
复制相似问题