当前位置: 首页 > 面试题库 >

Java线程和内核数

司马腾
2023-03-14
问题内容

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

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

预先感谢您的帮助。


问题答案:

进程与线程

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

并行与并发

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

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

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

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

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

因此, 出于我们的目的 ,可以将并行性视为并发的特殊情况*

排程

但是,我们能够生成一个线程池(比方说30个),该线程池的数量要大于我们所拥有的内核(让我们说4个)的内核数量,并使它们并发运行。如果我们只有4个核心,这怎么可能?

在这种情况下,它们可以并发运行,因为CPU调度程序为这30个线程中的每个线程分配了一部分CPU时间。某些线程
并行运行(如果您有4个核心,则任何时候4个线程将同时并行运行),但是所有30个线程将同时运行。之所以可以去玩游戏或浏览网络,是因为这些新线程被添加到线程池/队列中,并且还分配了一部分CPU时间。

逻辑与物理核心

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

这不是 真实。由于非常聪明的硬件设计和流水线工作太长了(我不理解),一个物理核心实际上可能同时执行 两个完全不同的执行线程
。如果需要的话,请稍稍咀嚼一下这句话-这仍然让我震惊。

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

有人可以解释它是如何工作的,并建议对此做一些很好的阅读吗?

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

  • 即使在我们自己的堆栈溢出中, 并行并发 术语的确切含义也引起了激烈的争论。这些术语的含义在很大程度上取决于应用程序领域。


 类似资料:
  • 问题内容: 我想用Java解决带有多个线程的数学问题。我的数学问题可以分为多个工作单元,我想通过几个线程来解决。 我不希望有固定数量的线程在工作,而是与CPU核心数量匹配的线程数量。我的问题是,为此我在互联网上找不到简单的教程。我发现的只是带有固定线程的示例。 如何才能做到这一点?你能提供例子吗? 问题答案: 你可以通过使用静态运行时方法,确定提供给Java虚拟机的进程数availableProc

  • 创建并执行内核线程 建立进程控制块(proc.c中的alloc_proc函数)后,现在就可以通过进程控制块来创建具体的进程/线程了。首先,考虑最简单的内核线程,它通常只是内核中的一小段代码或者函数,没有自己的“专属”空间。这是由于在uCore OS启动后,已经对整个内核内存空间进行了管理,通过设置页表建立了内核虚拟空间(即boot_cr3指向的二级页表描述的空间)。所以uCore OS内核中的所有

  • 我已经阅读了一些基于这个主题的注释,虽然我对线程有了一般的理解,但我并不确定用户级线程和内核级线程之间的区别。 我知道进程基本上由多个线程或单个线程组成,但这些线程是前面提到的两种类型吗? 据我所知,内核支持的线程可以访问内核进行系统调用和其他用户级线程不可用的用途。 那么,用户级线程仅仅是程序员在使用内核支持的线程执行由于其状态而不能正常执行的操作时创建的线程吗?

  • 调度并执行内核线程 initproc 在uCore执行完proc_init函数后,就创建好了两个内核线程:idleproc和initproc,这时uCore当前的执行现场就是idleproc,等到执行到init函数的最后一个函数cpu_idle之前,uCore的所有初始化工作就结束了,idleproc将通过执行cpu_idle函数让出CPU,给其它内核线程执行,具体过程如下: void cpu_i

  • 创建第 1 个内核线程 initproc 第0个内核线程主要工作是完成内核中各个子系统的初始化,然后就通过执行cpu_idle函数开始过退休生活了。所以uCore接下来还需创建其他进程来完成各种工作,但idleproc内核子线程自己不想做,于是就通过调用kernel_thread函数创建了一个内核线程init_main。在实验四中,这个子内核线程的工作就是输出一些字符串,然后就返回了(参看init

  • 创建第 0 个内核线程 idleproc 在init.c::kern_init函数调用了proc.c::proc_init函数。proc_init函数启动了创建内核线程的步骤。首先当前的执行上下文(从kern_init 启动至今)就可以看成是uCore内核(也可看做是内核进程)中的一个内核线程的上下文。为此,uCore通过给当前执行的上下文分配一个进程控制块以及对它进行相应初始化,将其打造成第0个