dpl*_*l47 17 cpu threads hyper-threading
我打开任务管理器并查看“系统”区域下,看到:
主题:1337
由于我有一个具有超线程可用的双核处理器(意味着四个线程),当我的处理器只应该有四个线程时,怎么可能有 1000 多个线程?
use*_*ser 51
简单的答案是并非所有线程都同时执行。如需更完整的解释,请继续阅读。
操作系统的任务调度程序通常被认为是调度应用程序,这样做允许您在计算机正在处理另一项任务时执行一项任务。在过去,多任务处理的试金石是在做其他事情的同时格式化软盘。如果您想真正测试操作系统,您可以在通过连接到串行端口的调制解调器下载文件时格式化软盘。随着硬件变得足够强大,可以以一种有意义的方式实际执行此操作,视频播放有时也会出现在此类测试中。如果操作系统的任务调度程序可以顺利运行这些任务,那么它就可以处理任何事情。
然而,任务调度器实际上并不调度应用程序(进程),它调度线程。每个应用程序至少有一个线程,但可能会使用大量线程将其所做的工作拆分为相关或独立的部分。例如,一个应用程序通常有一个线程来处理用户界面,并在用户启动一个潜在的长时间运行的操作时创建另一个线程(这可能是诸如打印、重新计算电子表格、开发环境执行符号查找等)。一些编程环境引入了一些对程序员不可见的线程;例如,Java和.NET可能会进行垃圾收集在一个单独的线程中,这是程序员的直接控制之外。一些程序会在早期创建多个线程并将它们池化,因为创建新线程是一项相对昂贵的操作(因此您不必每次需要一个线程时都必须创建一个线程)。任何进行预览的操作通常都在单独的线程中完成,因此在生成预览时 UI 的其余部分保持响应。等等。综上所述,这一切意味着系统上任何时候的线程数很容易是进程数的数倍。
每个线程都可以处于几种可能的状态之一,但最重要的区别是running、runnable和waiting状态;术语可能略有不同,但这是总体思路。在任何时候,每个虚拟(因为超线程和类似技术)只有一个线程可以运行(即执行机器代码指令),但可以运行任意数量的线程(意味着它是获得CPU 下次调度程序需要决定应该允许哪个线程运行时)。等待 (也称为阻塞)线程只是在等待某些东西 - 最常见的情况可能是它正在等待用户、磁盘或网络 I/O(尤其是用户输入异常缓慢)。
您在任务管理器中看到的线程数是处于任何这些状态的线程总数。例如,我正在输入的 Windows 7 系统当前启动了大约 70 个进程,但有近 900 个线程。有了处理各种任务的所有后台进程,以及它们可能如何细分为多个线程,这并不是一个惊人的数字。
深入技术实现的深度,抢先式多任务操作系统的任务调度程序的核心通常是某种硬件中断挂钩。这意味着内核可以停止CPU的时候它没有执行有用的工作(这是几乎可以肯定的原因之一,如果不是的理由,为什么Linux的检查的HLT
指令,在启动的IA-32-兼容的 CPU,并可能对其他架构进行类似的检查),知道在某个合理确定的未来时间,将触发中断并调用任务调度程序是安全的。由于无论 CPU 正在执行什么其他工作都会触发中断(这就是中断背后的想法),调度程序会定期执行,并有机会确定在接下来的时间片内应该执行哪个线程。由于上下文切换相对昂贵,因此通常可以(至少通过源代码)调整调度程序在线程之间切换的积极程度;更频繁地切换线程会导致系统响应更快,但切换开销意味着完成给定任务集的总时间更长。该最快系统将是一个仅在正在运行的线程不再可能运行时才在线程之间切换的系统(意味着它被阻塞等待某事,或者它已经完成了它的工作),因为这最小化了开销,而响应最快的系统将在线程之间切换每次调用调度程序时,因为这样可以最小化特定线程获得 CPU 时间之前的平均等待时间。理想的设置通常介于这两者之间,而这些选择之间的权衡可能是 Linux 提供多个调度程序以供选择以及通过内核配置提供一些调整参数的一个重要原因。
另一方面,协同多任务操作系统和环境(Windows 3.x就是一个例子)依赖于每个应用程序定期将控制权交给调度程序。通常有一个专门用于执行此操作的 API 函数,并且通常许多 API 函数会将其作为其内部执行流程的一部分来执行,因为它有助于使用户体验更流畅。只要所有应用程序都表现良好并且在任何长时间运行的操作(长时间运行意味着超过一小部分秒)期间以较短的时间间隔放弃控制,这种设计方法就可以很好地工作,但不会阻塞的应用程序整个系统。这是 Windows 3.x 在我上面提到的多任务测试中表现如此糟糕的一大原因,而OS/2在相同硬件上执行相同任务的同时愉快地漫步:应用程序可以告诉软盘驱动器写入某个扇区,并且在调用返回之前这样做所花费的时间实际上是可以测量的(几十到几百毫秒或更多的); 抢先式多任务系统将在其下一次调度调用时中断其调度程序,请注意当前“正在运行”的线程实际上被写入调用阻塞,只需切换到另一个可运行的线程即可。(在实践中它会涉及更多,但这是总体思路。)
在抢占式多任务和协作环境中,也存在不同线程具有不同优先级的可能性。例如,及时执行通过通信链路接收数据的线程可能比更新系统时间显示的线程更重要,因此接收线程具有高优先级而时间显示更新程序线程具有低优先级. 线程优先级在调度程序决定允许执行哪个线程中起作用(例如,非常简化的,高优先级线程应该始终在低优先级线程之前执行,因此即使低优先级线程还有工作要做,如果高优先级线程变为可运行,则优先),但这种特定的调度决策不会影响底层机制设计。
174*_*140 18
想想一条有 1037 辆车的四车道高速公路。
您的操作系统需要大量正在运行的进程才能为大量服务工作。即使是最简单的图形程序也需要多线程编程。当您想到打开的许多程序时,您会发现需要共享计算能力资源。
您的任务管理器显示的是当前系统负载。您的 comp 规范显示的是(在前端)接受并行执行的线程数。无需过多讨论超线程和多核功能之间的区别,只要有更多的逻辑前端线程接受,系统通常会表现得更好。
我们应该退后一步问问自己:单CPU的计算机怎么会有两个线程?
线程是软件实体,而不是硬件。要拥有另一个线程,您只需要用于构成线程的对象的内存,例如描述符结构和堆栈。
操作系统在不同时间在线程之间切换,例如在某些中断(例如定时器中断)内或当线程调用操作系统时。
在系统中存在的所有线程中,通常只有一个子集处于通常称为“可运行”的状态。可运行线程渴望运行:它们要么正在执行,要么位于“运行队列”中,等待调度程序调度。不可运行的线程被“阻塞”,等待获取一些资源或接收输入,或者“睡眠”,就像在输入时被阻塞,其中“输入”是时间的流逝。当操作系统中的调度程序功能查看处理器的运行队列并选择不同的线程来执行时,就会发生“上下文切换”。
不要被“超线程”混淆,这是英特尔对特定硬件功能的名称。
归档时间: |
|
查看次数: |
16714 次 |
最近记录: |