[top命令]解决Linux讨论哪些操作系统理论的概念定义没意义-工程与理论的差异
[top命令]解决Linux讨论哪些操作系统理论的概念定义没意义-工程与理论的差异
在Linux中进程和线程的相同点远大于不同点!
学术设计的逻辑理论上:进程和线程分别要用进程控制块(PCB)和线程控制块(TCB)
工程实际上:在Linux中无论进程或线程都被抽象为了任务(task),在源代码中是用task_struct结构体来实现的!【所以请一定要记住!Linux中的进程和线程我们一律叫task】
工程验证一下!你看人家top命令显示的!Tasks而不是你想象的什么Process或者Thread单词
whoway@devos:~/webservice$ top
top - 23:28:07 up 14 days, 11:59, 2 users, load average: 0.02, 0.04, 0.01
Tasks: 140 total, 1 running, 139 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.5 us, 0.5 sy, 0.0 ni, 99.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 1613.1 total, 117.3 free, 690.6 used, 980.0 buff/cache
MiB Swap: 0.0 total, 0.0 free, 0.0 used. 922.5 avail Mem在Linux新的源码中,其实task_struct结构体里面有2个id,一个叫pid,一个叫tgid
其实设计得挺有歧义的,但是其实也是类似大型公司:能复用原始的设计就复用一点吧
在Linux中设计这2个pid是为了支持:轻量级进程(也就是为了学术界所谓的线程)
其实Linux最原始版本只设计了1个pid也就是process id的简写
请记住现在Linux源码中pid和tgid的使用场景!
- pid还是沿用最原始Linux的设计,反正每个task都要给个pid呗;这时候可能读者就会问,那咋支持什么轻量级的进程啊,那每个task都给个pid还轻量啥轻量,不都是很重的task吗?
- 其实不然,linux的轻量级进程的轻量实现是通过设置各种标记:看你是不是要和父task共享某些东西?还是自己copy一份分家?还是咋的,反正工程实现就是很灵活,没那么死板;比如接下来要讲解的tgpid其实也算是一个小的实现点
- tgpid:因为学术界设计的逻辑理论,我如果1个逻辑进程创建了多个逻辑线程,那总要告诉我所属吧,所以linux设计了tgpid:表示自己这个pid具体所属的进程ID是哪个
- 典型的,linux的系统调用getgpid返回的就是tgpid【这种语义确实很奇怪哈!反正就是为了工程上的兼容】
- 因为最原始,只有pid,getgpid的语义就是:获取进程id
- 现在要支持逻辑线程,而针对1个线程支持所谓的获取进程id,这可不是被迫直接给返回个tgpid吧,根本不敢返回所谓的pid啊,待会人家Linux项目的前向兼容性全挂了!
- 典型的,linux的系统调用getgpid返回的就是tgpid【这种语义确实很奇怪哈!反正就是为了工程上的兼容】
top命令显示的疑问,关于Tasks、Threads、PID
那我在linux下执行1个top命令:
1、最左上方的Tasks是linux线程还是进程数目呢?
答案:进程数目
top - 10:30:00 up 1 day, 2:30, 1 user, load average: 0.15, 0.10, 0.05
Tasks: 250 total, 1 running, 249 sleeping, 0 stopped, 0 zombie这里的 Tasks: 250 total 实际上是:进程(Processes)的数量,不是线程数量!
只有当你top进入后,使用shift+h进入线程模式,你就会发现Tasks变了,成为Threads了【是的,这也展示了。。。历史上linux最开始只有进程,没有线程,所以top命令打的补丁是这样的!为的就是怕升级后,人家有些监控使用的top默认模型的Tasks,如果你把定义改了,人家系统就崩了!前向兼容!】
top - 15:43:47 up 15 days, 4:15, 3 users, load average: 0.00, 0.02, 0.00
Threads: 344 total, 2 running, 342 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.5 us, 1.0 sy, 0.0 ni, 98.4 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 1613.1 total, 177.3 free, 692.1 used, 918.5 buff/cache
MiB Swap: 0.0 total, 0.0 free, 0.0 used. 921.0 avail Mem2、top命令左边那一列PID到底是指的:pid还是tgpid呢?或者说top能显示tgpid吗?
答案:要看top命令的处于的模式!
聪明的你,从linux每次源码变更,基本上都要前向兼容,肯定猜到了!
- 默认模式(进程视图):
top - 15:47:22 up 15 days, 4:19, 3 users, load average: 0.00, 0.01, 0.00
Tasks: 137 total, 1 running, 136 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.6 us, 0.8 sy, 0.0 ni, 98.5 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 1613.1 total, 179.0 free, 690.3 used, 918.7 buff/cache
MiB Swap: 0.0 total, 0.0 free, 0.0 used. 922.8 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
21756 pcp 20 0 1426700 188620 11904 S 0.3 11.4 13:04.11 mysqld
299 root 19 -1 140596 78708 77556 S 0.0 4.8 0:30.21 systemd-journal
1202 root 20 0 2053704 37160 12800 S 0.0 2.2 2:35.09 dockerd- PID 列显示的是 **进程ID**
- 每个进程只显示一行
- CPU/MEM 是进程所有线程的总和
- 线程模式(按 H 或 top -H):
top - 15:47:09 up 15 days, 4:18, 3 users, load average: 0.00, 0.01, 0.00
Threads: 342 total, 1 running, 341 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.8 us, 0.8 sy, 0.0 ni, 98.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 1613.1 total, 179.0 free, 690.4 used, 918.6 buff/cache
MiB Swap: 0.0 total, 0.0 free, 0.0 used. 922.7 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
21756 pcp 20 0 1426700 188620 11904 S 0.0 11.4 0:00.36 mysqld
21859 pcp 20 0 1426700 188620 11904 S 0.0 11.4 0:00.00 mysqld
21861 pcp 20 0 1426700 188620 11904 S 0.0 11.4 0:45.45 mysqld- PID 列实际上显示的是 **线程ID(TID)**
- 同一个进程的不同线程会有相同的进程名
- 可以通过 `SPID`(有些系统是 `LWP`)字段看到线程ID
1.Linux中task的状态
| 状态码 | 状态描述 |
| D (TASK_UNINTERRUPTIBLE) | 不可中断的睡眠状态 |
| R (TASK_RUNNING) | 正在运行,或在队列中的进程 |
| S (TASK_INTERRUPTIBLE) | 可中断的睡眠状态 |
| T (TASK_STOPPED) | 停止状态 |
| t (TASK_TRACED) | 被跟踪状态 |
| Z (TASK_DEAD - EXIT_ZOMBIE) | 退出状态,但没被父进程收尸,成为僵尸状态 |
| W | 进入内存交换(从内核2.6开始无效) |
| X (TASK_DEAD - EXIT_DEAD) | 退出状态,进程即将被销毁 |
工程验证一下!还是看top命令
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2885 root 20 0 143388 27160 11392 S 1.7 1.6 268:50.07 AliYunDunMonito
1076 root 20 0 1315208 14508 11008 S 0.7 0.9 209:00.08 argusagent
795 root 20 0 686548 10608 6528 S 0.3 0.6 23:22.37 aliyun-service
893 root 20 0 1790676 23920 9216 S 0.3 1.4 13:52.24 containerd
1103 root 20 0 112444 29464 7424 S 0.3 1.8 119:09.51 AliYunDun
598423 polkitd 20 0 308164 7936 7168 S 0.3 0.5 0:02.92 polkitd
1 root 20 0 22564 11580 7228 S 0.0 0.7 0:47.07 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.28 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 0:00.00 pool_workqueue_release
4 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 kworker/R-rcu_g2.针对Linux的task状态再复杂一点
| 标记 | 描述 |
| < | 高优先级 |
| N | 低优先级 |
| L | 有些页被锁进内存 |
| s | 包含子进程 |
| + | 位于前台的进程组 |
| l | 多线程,克隆线程 (using CLONE_THREAD, like NPTL pthreads do) |
所以,有时候你会发现top命令可能会显示: Ss、Sl、S+、Z、I<
你现在就能明白了,top命令显示人家task的最真实的状态:是基础task状态加上标记,分成2部分看!!【一定要牢记!】
- 第1部分是状态
- 第2部分【如果有】那就是优先级之类的东西!
工程验证一下!还是看top命令