术语表/CPU、GPU和能耗

线程

又称:线程数

简要回答

线程是进程内部一条独立的执行路径,一个进程可以在不同的CPU内核上同时运行多个线程。活动监视器中的“线程”列显示每个进程当前有多少个线程。

大多数App都会用很多线程:一个负责绘制界面、处理点按,其他的负责网络请求、文件读写和后台工作。对大型App来说,几十个线程很正常。

线程数量几乎说明不了一个App有多忙。大多数线程都在等待。要看实际工作量,“% CPU”是更好的指标。

在哪里查看线程数

在活动监视器中点按“CPU”标签页。“线程”列显示每个进程的线程数,窗口底部则显示这台Mac上线程和进程的总数。

在“终端”中,ps -M -p <PID>会列出单个进程的线程。

线程数持续增长什么时候需要注意

线程数在几个小时里一直攀升、始终不见平稳,可能说明某个App有bug:不停地开启线程却从不结束它们。如果这个App的内存也在增长或者变慢了,先重新启动它是合理的第一步,把问题报告给开发者也有帮助。

为什么有些App有几百个线程

macOS通过Grand Central Dispatch为App提供一个共享的工作线程池。当一个App分派出很多小任务,比如解码图像或读取文件时,线程池会扩大来处理它们,之后再缩小。光这一点,就可能给一个忙碌的App增加几十个线程。

浏览器、聊天App和代码编辑器常常运行多个进程,每个进程都有自己负责绘制、网络、音频和脚本的线程。音频和视频App会让线程随时待命,这样播放就不用等待。把这些加起来,一个大型App有几百个线程并不稀奇。

kernel_task的线程数常常是所有进程中最多的。它容纳着macOS内核及其驱动程序使用的线程,这并不说明有问题。

如何查看单个App的线程数

  1. 在活动监视器中选择该进程并连按它,或者点按工具栏中的“信息”按钮。
  2. 检查器窗口会列出该进程的“线程”,以及“端口”和“上下文切换”。
  3. 在“终端”中运行top -l 1 -pid <PID> -stats pid,command,th,把<PID>换成“PID”列中的进程ID。#TH值先显示线程总数,斜杠后面是正在运行的线程数。
  4. 要按线程数给所有进程排序,运行top -o th -stats pid,command,th,按q退出。

正常的与值得担心的线程数

总数没那么重要,重要的是它随时间变化的方向。

  • 正常:打开窗口、开始下载或开始导出时线程数跳升,工作完成后又降回来。
  • 正常:线程数虽高但很稳定,几个小时都差不多。
  • 值得担心:线程数一整天都在攀升,从不下降,即使App闲着也一样。
  • 值得担心:线程数攀升的同时,内存或“端口”数也在增长。这种组合通常说明App存在泄漏。
  • 值得担心:一个你没在用的App有很多正在运行的线程(见top中斜杠后面的数字)。它在做你没要求它做的工作。

线程与CPU内核

线程比内核多是正常的。macOS每秒会在线程之间切换内核很多次,而且大多数线程本来就在等待。只有正在运行的线程才会争夺内核。

同一时刻能运行的线程数,等于sysctl -n hw.logicalcpu给出的逻辑内核数。如果准备就绪的线程比这更多,多出来的就得等待,正是这种等待让平均负载升高。

常见问题

活动监视器中的“线程”是什么意思?

它是一个进程正在运行的线程数。线程让一个App能同时做几件事,比如一边绘制窗口,一边下载文件。

线程数多是坏事吗?

通常不是。大型App往往有几十甚至几百个线程,其中大多数都闲着。需要留意的是线程数不停增长。

线程和“% CPU”超过100有什么关系?

只有当一个进程同时有不止一个线程在工作时,它才能用到不止一个内核。“% CPU”就是这样超过100%的。

Mac同一时间能运行多少个线程?

同一时刻每个逻辑内核运行一个。运行sysctl -n hw.logicalcpu可以看到这个数字。线程可以再多出成千上万个,但它们要轮流运行。

退出App会释放它的线程吗?

会。进程结束时,它所有的线程都会随之结束。要重置增长过多的线程数,重新启动App是最快的办法。

为什么kernel_task有这么多线程?

kernel_task就是macOS内核,它的线程包括内核及其驱动程序使用的线程。它的线程数多是正常的。

相关条目

想找比活动监视器更好的工具?请看Mac上最好用的活动监视器替代品,或者浏览术语表中的所有条目。