单核上多线程的重点是什么?

时间:2016-05-14 12:20:18

标签: multithreading cpu

我最近一直在玩Linux内核并重新回到大学的OS课程时代。

就像那时候一样,我正在玩线程之类的东西。这段时间我一直在假设线程自动在多个内核上同时运行,但我最近发现你实际上必须明确代码来处理多个内核。

那么单核上多线程的重点是什么?我能想到的唯一例子是在写一个客户端/服务器程序时来自大学,但这似乎是一个弱点。

4 个答案:

答案 0 :(得分:16)

  

这段时间我一直在假设线程是自动的   我在多个内核上同时运行,但我最近发现了   您实际上必须显式编码以处理多个核心。

对于任何广泛使用的现代操作系统,上述内容都是错误的。例如,所有Linux的调度程序将自动调度不同内核上的线程,甚至在必要时自动将线程从一个内核移动到另一个内核,以最大限度地提高内核使用率。有一些API允许您修改调度程序'行为,但这些API通常用于禁用自动线程到核心的调度,而不是启用它。

  

那么单核上多线程的重点是什么?

想象一下,您有一个GUI程序,其目的是执行昂贵的计算(例如,渲染3D图像或Mandelbrot集),然后显示结果。让我们说这个计算需要30秒才能在这个特定的CPU上完成。如果以显而易见的方式实现该程序,并且仅使用单个线程,则在执行计算时,用户的GUI控件将无响应30秒 - 用户将无法对您的程序执行任何操作,并且可能根本无法对他的电脑做任何事情。由于用户希望GUI控件始终具有响应性,因此用户体验不佳。

如果用两个线程(一个GUI线程和一个渲染线程)实现该程序,另一方面,用户将能够单击按钮,调整窗口大小,退出程序,选择菜单项等,甚至计算正在执行时,因为操作系统能够唤醒GUI线程并允许它在必要时处理鼠标/键盘事件。

当然,可以用一个线程编写这个程序并保持其GUI响应,通过编写单个线程来进行几毫秒的计算,然后检查是否有可用于处理的GUI事件,处理它们,然后回去做更多的计算,等等。但是如果你用这种方式编写应用程序,你实际上是在你的应用程序中编写自己的(非常原始的)线程调度程序,那么为什么要重新发明轮子?

MacOS的第一个版本设计为在单核上运行,但没有真正的多线程概念。这迫使每个应用程序开发人员正确地实现一些手动线程管理 - 即使他们的应用程序没有任何扩展计算,他们也必须明确指出何时使用CPU完成,例如致电WaitNextEvent。由于只有一个写得不好的应用程序可能会使整个计算机停止运转,因此缺少多线程使MacOS的早期(MacOS-X之前版本)版本显得不可靠。

答案 1 :(得分:1)

好吧,当你说单核上的多线程时,你需要考虑一些事情。例如,您正在使用的线程API - 用户级别或内核级别。最有可能来自你的问题我相信你正在使用用户级线程。 现在,用户级线程,取决于主机操作系统或API本身可以映射到单个内核线程或多个。许多关系是可能的,如1-1,多-1或许多。 现在,如果只有一个核心,您的操作系统仍然可以为您提供多个内核级别线程,这些线程可能表现为CPU的多个进程。在这种情况下,操作系统将为内核线程提供时间切片(和多编程),从而实现超高速上下文切换,并通过用户级API - 您/您的代码似乎具有多线程功能。 另请注意,尽管您的处理器是单核,但取决于make,它可以是超线程的,并且具有超深管道,允许以非常低的开销同时运行内核线程。 供参考:检查Intel / AMD架构以及各种操作系统如何提供内核线程。

答案 2 :(得分:1)

首先,程序不仅要计算,还要等待输入/输出,因此可以认为是在I / O处理器上执行。因此即使是单核机器也是一台多处理器机器,采用多线程是合理的。

其次,为了模块化,任务可以划分为多个线程。

答案 3 :(得分:1)

多线程不仅仅是为了利用多核心。

您需要多个进程才能进行多任务处理。出于类似的原因,您可以拥有多个线程,与进程相比,它们是轻量级的。

您可能不希望一直生成进程,例如阻止I / O.这可能有点矫枉过正。

还有纤维,更轻盈。因此,我们有针对不同需求水平的流程,线程和光纤。