多线程实际上在单处理器环境中工作吗

时间:2018-12-14 15:25:59

标签: multithreading operating-system

假设我们在一个单处理器中有一个带有多个线程的进程。 现在我知道,如果我们有多个进程,则一次只能在一个处理器中处理一个进程,因此这些进程不是并发的。
如果我的理解是正确的,类似地,每个线程将一次处理,并且不会在单处理器中并发。这句话是真的吗?如果是这样,那么多线程是否意味着一个进程中有多个线程,并不意味着一次运行多个线程?这是否意味着在单处理器环境中创建用户线程没有任何好处?

4 个答案:

答案 0 :(得分:3)

TL; DR:线程切换的速度比进程切换的速度更快,并且实时发生并发的影响,因为并发发生的速度非常快。

您写的时间:

  

每个线程将一次处理,而不是在单处理器中并发

请注意“并发”一词,单处理器中没有真正的并发,只有进程之间存在大量上下文切换,这才有效果。

在这里让我们澄清一下,CPU的单个内核可以在给定的时间处理一个线程,每个进程都有一个主线程,并且(如果需要)可以同时运行多个线程。如果进程A现在正在运行,并且具有3个线程:A1(主线程),A2,A3,则只要CPU内核正在处理进程A,这三个线程都将运行。当发生上下文切换时,进程A不再运行,现在进程B将使用其线程运行。

关于此声明:

  

在单处理器环境中创建用户线程没有好处

那是不对的。创建线程有一个好处,它们更容易创建(如书中的“ spawn”)和减少进程堆内存。与线程相比,创建子进程(在书中称为“子”)是一项开销,因为一个进程需要拥有自己的内存。例如,每个google chrome标签都是一个进程而不是线程,但是此标签有多个线程并发运行,几乎没有责任。

答案 1 :(得分:1)

如果仍然以某种方式运行仅具有一个单核CPU的计算机,则可以正确地观察到一次只能执行一个线程。但这并不会否定将应用程序分成多个线程和/或进程的价值。

基本好处是 并发 。当一个线程在等待(例如,完成输入/输出操作)时, CPU会同时执行其他操作:它可以运行 isn 't 等待。通过精心设计的应用程序,您可以更好地利用硬件的每个部分,提高并行度,从而提高吞吐量。

我最喜欢的示例是快餐店。 合作大约有十几个工人,每个人做不同的事情,将订单交给您。即使其中一个(例如,“炒小子”)站着,其他人总是有事要做。几个订单正在处理中。无论您有多少CPU,这个重叠这个“并发”都是您要拍摄的内容。

多线程也通常与GUI应用程序一起使用,它们也需要执行某种“繁重的工作”。一个线程处理GUI交互(没有其他实际职责),而其他线程的 priority (或“ niceness”)稍差一些。当一个GUI事件进入时,GUI线程先抢占并立即响应它,然后当然又回到睡眠状态。但是通过这种方式,GUI始终保持非常高的响应速度-即使其他线程在做“繁重的工作”,GUI消息仍然可以非常迅速地处理。 (我通过重新构建旧版应用程序以使用这种方法而获得了25%的性能提升,因为该应用程序不再针对GUI事件进行“轮询”。)

答案 2 :(得分:1)

关于任何线程,我要问的第一个问题是:“ 等待是做什么用的?”对我来说,线程是由它等待的事件 和事件发生时的行为来定义的。

在多处理器计算机商用之前,线程已被广泛使用了至少十年。当您要编写必须响应来自多个不同来源的未同步事件的程序时,它们很有用。有几种不同的方法可以对这样的程序进行建模。一种方法是让不同的线程等待每个不同的事件源。接下来最受欢迎的是event driven architecture,其中有一个主循环等待所有事件,并为每种不同类型的事件调用不同的事件处理函数。

程序的多线程样式通常更易于阅读*,因为程序内部通常会进行不同的活动,并且每个活动的状态都可以隐含在 context 中(即寄存器和调用堆栈)驱动它的线程,而在事件驱动模型中,每个活动的状态必须明确地编码在某个对象中。

保持状态的隐式上下文方式非常类似于 procedural style ,它编码了我们初学者学习的单个活动。


*更容易 read 并不意味着该代码易于 write 而不造成不良和非显而易见的错误!

答案 3 :(得分:0)

开发线程的主要动力是Ada合规性。在此之前,不同的操作系统具有自己的一次性处理多个事务的方式。太监认为,要做不止一件事情的方法就是剥离一个新的过程。在VMS中,软件会中断(又称“异步系统陷阱”或Windoze中的“异步过程调用”)。在那时(1970年代),多处理器系统很少见。

Ada的目标之一是拥有独立于系统的做事方式。它采用了实际上是线程的“任务”。为了支持Ada,编译器开发人员必须包括任务(线程)库。

随着多处理器的兴起,操作系统开始使线程(而不是进程)成为系统中的基本可调度单元。

然后,即使只有一个处理器,线程也为程序提供了一种同时处理多种事物的方法。可悲的是,严重缺乏对编程语言中线程的支持。 Ada是我能想到的唯一对线程(任务)有真正支持的主要语言。例如,Java中的线程支持是一个完全的恶作剧。结果是线程在实践中没有达到应有的效果。