go如何实时监测当前进程生成的goroutine协程数量?
runtime.NumGoroutine()
返回当前的运行时的go协程数。
Linux 查看进程的线程数
三种方法:
1。 使用top命令,具体用法是 top -H
加上这个选项,top的每一行就不是显示一个进程,而是一个线程。
2。 使用ps命令,具体用法是 ps -xH
这样可以查看所有存在的线程,也可以使用grep作进一步的过滤。
3。 使用ps命令,具体用法是 ps -mq PID
这样可以看到指定的进程产生的线程数目。
1.根据进程号进行查询:
2.根据进程名字进行查询:
ps -e | grep server | awk '{print $1}'
ps -e | grep server | awk '{print $1}'
| wc -l更进一步,其实一些系统监控工具,在本质上也是读取的系统产生的文件罢了。比如说进程这个事情,
现在假设有进程号为 5000 的进程,查看这个进程的所有具体信息,在哪查看呢?
看看这个目录吧,/proc/5000/ 这里面有你所有想要的。其实stat代表着当前的一些信息。
使用ps命令来查看进程的时候,进程状态分别对应的含义如下:
D 不可中断睡眠 (通常是在IO操作) 收到信号不唤醒和不可运行, 进程必须等待直到有中断发生
R 正在运行或可运行(在运行队列排队中)
S 可中断睡眠 (休眠中, 受阻, 在等待某个条件的形成或接受到信号)
T 已停止的 进程收到SIGSTOP, SIGSTP, SIGTIN, SIGTOU信号后停止运行
W 正在换页(2.6.内核之前有效)
X 死进程 (未开启)
Z 僵尸进程 进程已终止, 但进程描述符存在, 直到父进程调用wait4()系统调用后释放BSD风格的
< 高优先级(not nice to other users)
N 低优先级(nice to other users)
L 页面锁定在内存(实时和定制的IO)
s 一个信息头
l 多线程(使用 CLONE_THREAD,像NPTL的pthreads的那样)
pstree以树结构显示进程
$ ps -Lf 1892
$ pstree -p 10536
xzm(10536)─┬─{xzm}(10537)
├─{xzm}(10538)
└─{xzm}(10539)
$ ps -Lf 10536
UID PID PPID LWP C NLWP STIME TTY STAT TIME CMD
xiaoju 10536 9374 10536 0 4 11:09 pts/0 Sl 0:00 ./xzm
xiaoju 10536 9374 10537 0 4 11:09 pts/0 Sl 0:00 ./xzm
xiaoju 10536 9374 10538 0 4 11:09 pts/0 Sl 0:00 ./xzm
xiaoju 10536 9374 10539 0 4 11:09 pts/0 Sl 0:00 ./xzm
乍一看,ps -Lf 比 pstree 多了一项,检查下LWP 这一列,发现id数是对应的,原因,ps -Lf 包含了父线程
$ ps -hH -p 10536
10536 pts/0 Sl 0:00 ./xzm
10536 pts/0 Sl 0:00 ./xzm
10536 pts/0 Sl 0:00 ./xzm
10536 pts/0 Sl 0:00 ./xzm
$ ps -mq 10536
PID TTY TIME CMD
10536 pts/0 00:00:00 xzm
- - 00:00:00 -
- - 00:00:00 -
- - 00:00:00 -
- - 00:00:00 -
package main
import (
“fmt”
“time”
)
func main() {
fmt.Println(“hello”)
time.Sleep(10000*time.Second)
}
这段代码有4个系统线程
[xiaoju@5ad7acb94725 ~]$ pstack 10536
Thread 1 (process 10536):
#0 runtime.futex () at /usr/local/go1.13.3/src/runtime/sys_linux_amd64.s:536
#1 0x0000000000427264 in runtime.futexsleep (addr=0x561380 <runtime.timers+32>, val=0, ns=9999999990864) at /usr/local/go1.13.3/src/runtime/os_linux.go:50
#2 0x0000000000409bbe in runtime.notetsleep_internal (n=0x561380 <runtime.timers+32>, ns=9999999990864, ~r2=
#3 0x0000000000409d1c in runtime.notetsleepg (n=0x561380 <runtime.timers+32>, ns=9999999990864, ~r2=
#4 0x0000000000444ff1 in runtime.timerproc (tb=0x561360
#5 0x0000000000453851 in runtime.goexit () at /usr/local/go1.13.3/src/runtime/asm_amd64.s:1357
#6 0x0000000000561360 in ?? ()
#7 0x0000000000000000 in ?? ()
[xiaoju@5ad7acb94725 ~]$ pstack 10537
Thread 1 (process 10537):
#0 runtime.futex () at /usr/local/go1.13.3/src/runtime/sys_linux_amd64.s:536
#1 0x0000000000427264 in runtime.futexsleep (addr=0x55ead0 <runtime.sched+272>, val=0, ns=60000000000) at /usr/local/go1.13.3/src/runtime/os_linux.go:50
#2 0x0000000000409bbe in runtime.notetsleep_internal (n=0x55ead0 <runtime.sched+272>, ns=60000000000, ~r2=
#3 0x0000000000409c91 in runtime.notetsleep (n=0x55ead0 <runtime.sched+272>, ns=60000000000, ~r2=
#4 0x00000000004355ae in runtime.sysmon () at /usr/local/go1.13.3/src/runtime/proc.go:4316
#5 0x000000000042dec3 in runtime.mstart1 () at /usr/local/go1.13.3/src/runtime/proc.go:1201
#6 0x000000000042ddde in runtime.mstart () at /usr/local/go1.13.3/src/runtime/proc.go:1167
#7 0x00000000004557d3 in runtime.clone () at /usr/local/go1.13.3/src/runtime/sys_linux_amd64.s:587
#8 0x0000000000000000 in ?? ()
[xiaoju@5ad7acb94725 ~]$ pstack 10538
Thread 1 (process 10538):
#0 runtime.futex () at /usr/local/go1.13.3/src/runtime/sys_linux_amd64.s:536
#1 0x00000000004271e6 in runtime.futexsleep (addr=0xc00009c4c8, val=0, ns=-1) at /usr/local/go1.13.3/src/runtime/os_linux.go:44
#2 0x0000000000409a3f in runtime.notesleep (n=0xc00009c4c8) at /usr/local/go1.13.3/src/runtime/lock_futex.go:151
#3 0x000000000042f2c0 in runtime.stopm () at /usr/local/go1.13.3/src/runtime/proc.go:1928
#4 0x00000000004303df in runtime.findrunnable (gp=0xc000026500, inheritTime=false) at /usr/local/go1.13.3/src/runtime/proc.go:2391
#5 0x000000000043108e in runtime.schedule () at /usr/local/go1.13.3/src/runtime/proc.go:2524
#6 0x00000000004313cd in runtime.park_m (gp=0xc000001200) at /usr/local/go1.13.3/src/runtime/proc.go:2610
#7 0x00000000004518eb in runtime.mcall () at /usr/local/go1.13.3/src/runtime/asm_amd64.s:318
#8 0x0000000000000000 in ?? ()
[xiaoju@5ad7acb94725 ~]$ pstack 10539
Thread 1 (process 10539):
#0 runtime.futex () at /usr/local/go1.13.3/src/runtime/sys_linux_amd64.s:536
#1 0x00000000004271e6 in runtime.futexsleep (addr=0xc00009c848, val=0, ns=-1) at /usr/local/go1.13.3/src/runtime/os_linux.go:44
#2 0x0000000000409a3f in runtime.notesleep (n=0xc00009c848) at /usr/local/go1.13.3/src/runtime/lock_futex.go:151
#3 0x000000000042f2c0 in runtime.stopm () at /usr/local/go1.13.3/src/runtime/proc.go:1928
#4 0x00000000004303df in runtime.findrunnable (gp=0xc000028a00, inheritTime=false) at /usr/local/go1.13.3/src/runtime/proc.go:2391
#5 0x000000000043108e in runtime.schedule () at /usr/local/go1.13.3/src/runtime/proc.go:2524
#6 0x00000000004313cd in runtime.park_m (gp=0xc000000c00) at /usr/local/go1.13.3/src/runtime/proc.go:2610
#7 0x00000000004518eb in runtime.mcall () at /usr/local/go1.13.3/src/runtime/asm_amd64.s:318
#8 0x0000000000000000 in ?? ()
对比发现:
10536 runtime.timerproc (tb=0x561360
10537 runtime.sysmon ()
10538 runtime.schedule ()
10539 runtime.schedule ()
说明除了主线程序和 sysmon线程,即使没有用户goroutine,系统也会启动两个空闲的M
查看进程总数
ps -ef | wc -l
1
查看系统设置的最大进程数
sysctl kernel.pid_max
1
查看当前进程数
ps -eLf | wc -l
1
修改最大进程数
echo “kernel.pid_max=1000000 “ » /etc/sysctl.conf
sysctl -p
1
2
查看某个服务的进程数
eg:http服务:
ps -ef | grep httpd | wc -l
1
查看物理cpu个数
grep ‘physical id’ /proc/cpuinfo | sort -u
1
查看核心数量
grep ‘core id’ /proc/cpuinfo | sort -u | wc -l
1
查看线程数
grep ‘processor’ /proc/cpuinfo | sort -u | wc -l
pstree以树结构显示进程
$ pstree -p work | grep ad
sshd(22669)—bash(22670)—ad_preprocess(4551)-+-{ad_preprocess}(4552)
|-{ad_preprocess}(4553)
|-{ad_preprocess}(4554)
|-{ad_preprocess}(4555)
|-{ad_preprocess}(4556)
`-{ad_preprocess}(4557)
work为工作用户,-p为显示进程识别码,ad_preprocess共启动了6个子线程,加上主线程共7个线程
进程共启动了7个线程
pstack显示每个进程的栈跟踪
$ pstack 4551
Thread 7 (Thread 1084229984 (LWP 4552)):
#0 0x000000302afc63dc in epoll_wait () from /lib64/tls/libc.so.6
#1 0x00000000006f0730 in ub::EPollEx::poll ()
#2 0x00000000006f172a in ub::NetReactor::callback ()
#3 0x00000000006fbbbb in ub::UBTask::CALLBACK ()
#4 0x000000302b80610a in start_thread () from /lib64/tls/libpthread.so.0
#5 0x000000302afc6003 in clone () from /lib64/tls/libc.so.6
#6 0x0000000000000000 in ?? ()
Thread 6 (Thread 1094719840 (LWP 4553)):
#0 0x000000302afc63dc in epoll_wait () from /lib64/tls/libc.so.6
#1 0x00000000006f0730 in ub::EPollEx::poll ()
#2 0x00000000006f172a in ub::NetReactor::callback ()
#3 0x00000000006fbbbb in ub::UBTask::CALLBACK ()
#4 0x000000302b80610a in start_thread () from /lib64/tls/libpthread.so.0
#5 0x000000302afc6003 in clone () from /lib64/tls/libc.so.6
#6 0x0000000000000000 in ?? ()
#ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 17236 17233 0 80 0 - 28946 wait pts/0 00:00:00 bash
0 R 0 17274 17236 0 80 0 - 37233 - pts/0 00:00:00 ps
每个项目的意义简单说明如下:
F (flag):代表程序的总结旗标,常见为4 代表root
S (stat):状态列,主要的分类项目有:
R (Running):该程式正在运作中;
S (Sleep):该程式目前正在睡眠状态(idle),但可以被唤醒(signal)。
D :不可被唤醒的睡眠状态,通常这支程式可能在等待I/O 的情况(ex>列印)
T :停止状态(stop),可能是在工作控制(背景暂停)或除错(traced) 状态;
Z (Zombie):僵尸状态,程序已经终止但却无法被移除至记忆体外。
UID/PID/PPID:代表『此程序被该UID 所拥有/程序的PID 号码/此程序的父程序PID 号码』
C:代表CPU 使用率,单位为百分比;
PRI/NI:Priority/Nice 的缩写,代表此程序被CPU 所执行的优先顺序,数值越小代表该程序越快被CPU 执行。
ADDR/SZ/WCHAN:都与记忆体有关,ADDR 是kernel function,指出该程序在记忆体的哪个部分,如果是个running 的程序,一般就会显示『 - 』 / SZ 代表此程序用掉多少记忆体/ WCHAN 表示目前程序是否运作中,同样的, 若为- 表示正在运作中。
TTY:登入者的终端机位置,若为远端登入则使用动态终端介面(pts/n);
TIME:使用掉的CPU 时间,注意,是此程序实际花费CPU 运作的时间,而不是系统时间;
CMD:就是command 的缩写,造成此程序的触发程式之指令为何。
pstree
程序关联树即pstree,为了显示的方便,建议-A 的选项, 以ASCII 的显示字元输出,比较不容易出现乱码:
systemd-+-NetworkManager-+-dhclient
| -2*[{NetworkManager}]
-tuned—4*[{tuned}]
|-2*[agetty]
|-auditd---{auditd}
|-chronyd
|-crond
|-dbus-daemon
|-dsp.jar---java---82*[{java}]
|-gapd---{gapd}
|-irqbalance
|-nginx---2*[nginx]
|-oms-server.jar---java---99*[{java}]
-----省略-------
若需要加上PID 与使用者资料, 可以直接使用-up 来加入即可
systemd(1)-+-NetworkManager(445)-+-dhclient(706)
| |-{NetworkManager}(455)
| `-{NetworkManager}(457)
|-agetty(625)
|-agetty(644)
|-dbus-daemon(429,dbus)
|-dgp-server.jar(2615,bootapp)—java(2663)-+-{java}(2664)
| |-{java}(2666)
——-底下省略——-
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 125196 2640 ? Ss 2019 23:56 /usr/lib/systemd/sy
root 2 0.0 0.0 0 0 ? S 2019 0:00 [kthreadd]
每一个项目代表的意义简易说明如下:
USER:该process 属于那个使用者帐号的
PID :该process 的程序识别码。
%CPU:该process 使用掉的CPU 资源百分比;
%MEM:该process 所占用的实体记忆体百分比;
VSZ :该process 使用掉的虚拟记忆体量(Kbytes)
RSS :该process 占用的固定的记忆体量(Kbytes)
TTY :该process 是在那个终端机上面运作,若与终端机无关则显示?,另外, tty1-tty6 是本机上面的登入者程序,若为pts/0 等等的,则表示为由网路连接进主机的程序。
STAT:该程序目前的状态,状态显示与ps -l 的S 旗标相同(R/S/T/Z)
START:该process 被触发启动的时间;
TIME :该process 实际使用CPU 运作的时间。
COMMAND:该程序的实际指令
top 动态观察程序
top 可以协助读者未来在管理程序的CPU 使用量上面的一个很重要的工具。直接输入top 即可每5 秒钟更新一次程序的现况
op 程式执行的状态列,每个项目的意义为:
PID :每个process 的识别码(PID)
USER:该process 所属的使用者;
PR :Priority 的简写,程序的优先执行顺序,越小越早被执行;
NI :Nice 的简写,与Priority 有关,也是越小越早被执行;
%CPU:CPU 的使用率;
%MEM:记忆体的使用率;
TIME+:CPU 使用时间的累加;
COMMAND:指令
在预设的情况下,top 所显示的程序会以CPU 的使用率来排序,这也是管理员最需要的一个观察任务。许多时候系统发生资源不足或者是效能变差的时候, 最简易的方法为使用top 观察最忙碌的几只程序,借以处理程序的效能问题。此外,也能透过top 观察I/O wait 的CPU 使用率, 可以找到I/O 最频繁的几只程序,借以了解到哪些程序在进行哪些行为,或者是系统效能的瓶颈,借以作为未来升级硬体的依据。
top - 10:22:33 up 34 days, 18:16, 1 user, load average: 6.41, 5.25, 4.66
1
代表目前为10:22:33 ,本系统开机了34 天又18:16 这的久的时间,目前有1 用户登入,工作负载为6.41, 5.25, 4.66 。那三个数据代表1, 5, 15 分钟内的平均工作负载。所谓的工作负载为『单一时间内,CPU 需要运作几个工作』之意,并非CPU 使用率。
Tasks: 92 total, 1 running, 91 sleeping, 0 stopped, 0 zombie
1
目前共有92个程序,其中1 个在执行,91个睡着了,没有停止与僵尸程序。
%Cpu(s): 27.6 us, 5.5 sy, 0.0 ni, 66.8 id, 0.0 wa, 0.0 hi, 0.2 si, 0.0 st
1
这里才是CPU 的使用率百分比,比较需要注意id (idle) 与wa (I/O wait),id 越高代表系统越闲置, wa 越高代表程序卡在读写磁碟或网路上,此时系统效能会比较糟糕。
如果你发现在某个程序的CMD 后面还接上 时,就代表该程序是僵尸程序啦,例如:
apache 8683 0.0 0.9 83384 9992 ? Z 14:33 0:00 /usr/sbin/httpd
https://www.cnblogs.com/FengGeBlog/p/10353275.html