Java线程和内核数量

我只是对处理器和线程如何工作提出了一个简短的问题。 根据我目前的理解,一个核心一次只能执行一个进程。 但是我们能够产生一个比我们拥有的核心数量更大的线程池(比如说30),并让它们同时运行。 如果我们只有4个内核,这怎么可能? 我也可以在本地计算机上运行30线程程序,并且还可以继续在计算机上执行其他活动,例如观看电影或浏览互联网。

我已经在某处看到线程调度发生,并且这种错觉给出了这4个核心同时运行这30个线程的错觉。 这是真的吗?如果有的话,有人可以解释这是如何工作的,并建议一些很好的阅读?

预先感谢您的帮助。


进程与线程

在过去的日子里,每个进程都只有一个执行线程,所以进程直接调度到内核中(而且在过去,几乎只有一个内核可以调度)。 但是,在支持线程的操作系统(几乎所有现代操作系统的操作系统)中,它都是线程,而不是预定的进程。 因此,对于本讨论的其余部分,我们将专门讨论线程,并且您应该了解每个正在运行的进程都有一个或多个执行线程。

并行与并发

当两个线程并行运行时,它们都在同时运行。 例如,如果我们有两个线程A和B,那么它们的并行执行如下所示:

CPU 1:A ------------------------->

CPU 2:B ------------------------->

当两个线程同时运行,它们的执行重叠。 重叠可以通过以下两种方式之一发生:或者线程同时执行(即并行执行,如上所述),或者它们的执行在处理器上交错执行,如下所示:

CPU 1:A -----------> B ----------> A -----------> B -------- - >

因此,为了我们的目的,并行性可以被认为是并发性的特例*

调度

但是我们能够产生一个比我们拥有的核心数量更大的线程池(比如说30),并让它们同时运行。 如果我们只有4个内核,这怎么可能?

在这种情况下,它们可以并发运行,因为CPU调度程序正在给这30个线程中的每一个分配一些CPU时间。 某些线程将并行运行(如果您有4个内核,那么同时有4个线程并行运行),但是所有30个线程将同时运行。 之后你可以玩游戏或浏览网页的原因是这些新线程被添加到线程池/队列中,并且还给出了CPU时间的份额。

逻辑与物理内核

根据我目前的理解,一个核心一次只能执行一个进程

这不完全正确。 由于非常聪明的硬件设计和流水线,这些时间太长而无法进入(另外我不理解它),因此一个物理内核可能同时执行两个完全不同的执行线程。 如果你需要的话,稍微嚼一下这句话 - 它仍然在打击我的思想。

这个惊人的壮举被称为同时多线程(或普遍超线程,尽管这是这种技术的特定实例的专有名称)。 因此,我们有物理内核 ,它们是实际的硬件CPU内核和逻辑内核 ,这是操作系统告诉软件可用的内核数量。 逻辑核心本质上是一个抽象。 在典型的现代英特尔CPU中,每个物理内核充当两个逻辑内核。

有人可以解释这是如何工作的,也推荐一些很好的阅读呢?

如果您真的想了解进程,线程和调度如何协同工作,我会推荐操作系统概念。

  • 并行和并发这两个术语的精确含义引起了热烈的争论,即使在我们自己的堆栈溢出中也是如此。 这些术语意味着什么取决于应用领域。

  • 简而言之,你对核心的理解是正确的。 一个核心可以一次执行1个线程(aka进程)。

    但是,您的程序不会一次真正运行30个线程。 在这30个线程中,一次只有4个正在运行,另外26个正在等待。 CPU将调度线程并为每个线程提供一段时间在核心上运行。 所以CPU将使所有线程轮流运行。

    一个常见的误解:

    拥有更多的线程将使我的程序运行得更快。

    FALSE:拥有更多的线程并不总是让你的程序运行得更快。 这只是意味着CPU必须进行更多的切换,事实上,线程太多将导致程序运行速度变慢,因为切换所有不同的进程会导致开销。


    Java不会执行线程调度 ,它会在操作系统上执行线程调度。

    对于计算密集型任务,建议使线程池大小等于可用内核数。 但是对于I / O绑定的任务,我们应该有更多的线程。 如果两种类型的任务都可用并需要CPU时间片,则还有许多其他变体。

    一个核心一次只能执行一个进程

    是的,但是他们可以同时进行多项任务并产生一种错觉 ,即他们正在处理多个流程

    如果我们只有4个内核,这怎么可能? 我也能够在本地计算机上运行我的30线程程序,并且还可以继续在我的计算机上执行其他活动

    这可能是由于多任务 (这是并发 )。 假设你开始了30个线程,并且OS也运行了50个线程,所有80个线程将逐个获取CPU时间片(每次一个内核一个线程),共享4个CPU内核。 这意味着平均每个核心将同时运行80/4 = 20个线程。 你会觉得所有的线程/进程都在同一时间运行。

    有人可以解释这是如何工作的

    所有这些都发生在操作系统级别 。 如果你是程序员,那么你不应该担心这一点。 但是,如果您是OS的学生,那么请选择任何操作系统书籍,并详细了解操作系统级别的多线程,或者查找一些有关深度的良好研究论文。 有一件事你应该知道,每个操作系统都以不同的方式处理这些事情(但通常概念是相同的)

    有一些像Erlang这样的语言,它们使用绿色的线程(或进程),因此他们可以在自己的操作系统上映射和调度线程。 因此,如果您有兴趣,也可以对绿线进行一些研究。

    注意:你也可以研究actor ,这是线程的另一个抽象 。 像Erlang,Scala等语言使用actor来完成任务。 一条线可以有上百个演员; 每个actor可以执行不同的任务(类似于java中的线程)。

    这是一个非常广泛和活跃的研究课题 ,有很多东西需要学习。

    链接地址: http://www.djcxy.com/p/13931.html

    上一篇: Java threads and number of cores

    下一篇: Why OCaml's threading is considered as `not enough`?