线程几乎没有开销;流程有相当大的开销。这是什么意思?

时间:2011-08-28 08:08:09

标签: multithreading

我在阅读Thread和Process之间的区别时遇到了这个陈述。请解释一下。

3 个答案:

答案 0 :(得分:2)

我认为它试图说创建一个新线程并在线程之间进行通信是合理有效/便宜的,而创建一个新流程并在流程之间进行通信相当低效/昂贵。

虽然这是一个全面的陈述 - 不同操作系统之间的成本差别很大。 Windows上的声明比大多数Unix实现(它试图使流程创建更便宜)更“真实”,甚至在Windows上,说“线程几乎没有开销”是不正确的。创建一个新线程仍然远非琐碎的操作。

答案 1 :(得分:2)

如上所述,它是如此广泛的概括,至少在某种程度上它几乎肯定是假的。我读过它说“线程通常比进程的开销要少得多。”

如果我们以这种方式阅读,通常至少在某种程度上是正确的。特别是,线程(至少在通常使用的术语中)共享一个地址空间,但进程(同样,通常使用的术语)具有单独的地址空间。

这意味着大多数进程间通信需要在用户模式和内核模式之间至少进行一次切换(通常是一对甚至更多)。可以在用户和内核模式之间没有任何切换的情况下完成相当多的线程间通信。 通常会减少开销。同时,即使(例如)Windows上的InterlockedIncrement也可能比简单(非互锁)增量具有相当多的更多开销。

请注意,我专注于通信和同步,而不是最初创建有问题的线程/进程。虽然 的情况下考虑线程/进程创建是有意义的,但它确实相当异常 - 创建进程一个线程通常有足够的开销,你通常希望确保它不会发生在任何紧密循环或类似的东西,如果你可以避免它。特别是,创建任何一个通常都需要切换到内核模式(再次可能多于一个)。进程/线程创建本身非常复杂,它们之间存在明显/可测量的差异,但切换到内核模式会带来相当大量的几乎不可避免的开销。

至于这些意味着什么,它相当简单:无论您是使用线程还是进程,您通常都希望预先创建一个池并将任务分派给池,而不是为每个出现的任务创建一个新的进程/线程。 (表面上有点)减少创建线程的开销并没有真正影响这一点。

您通常希望/需要在两者之间进行不同设计的地方是您提供的任务大小,以及通信的粒度和频率。使用进程池,您希望任务相对较大,并且通信很少能避免过多的开销。使用线程,您可以使用较小的任务和更频繁的通信,而不必担心开销几乎一样多。

然而,相反,它也很容易夸大差异。我们通常会谈论几个数量级左右的事情。如果您希望(例如)从分派到线程池的任务一毫秒一次更新,那么您可能希望使用进程池将其减慢到每100毫秒左右,但是在诸如此类之类的事情之间需要长时间的暂停不需要状态更新来减少开销。

答案 2 :(得分:0)

进程有自己的内存,自己的FD集,自己的内存映射,自己的动态库集以及自己的线程集。相比之下,所有线程都有堆栈,PC和寄存器集。为了简化。

相关问题