检查Linux中每个进程(线程与进程)的线程数
在Linux中,某些进程被分成称为线程的部分。在一种情况下,"线程本质上只是Linux上具有共享地址空间的进程"。
在本文中,我们将获得一些"关于线程和进程的简要概述",还提供了一些示例来显示每个进程的线程,检查每个进程的线程数,检查允许的线程数,计数线程以及更多相关主题。
线程与进程区别
线程与进程非常相似,它具有标识符(TID或者线程ID),并且内核像进程一样调度和运行线程。
但是,与通常不与其他进程共享诸如内存和I/O连接之类的系统资源的独立进程不同,单个进程内的所有线程都共享其系统资源和某些内存。
具有一个线程的进程是单线程的,具有多个线程的进程是多线程的。
所有进程都从单线程开始。该起始线程通常称为主线程。然后,主线程可以启动新线程,以使进程成为多线程,类似于进程可以调用fork()来启动新进程的方式。
多线程进程的主要优点是,当该进程有很多工作要做时,线程可以在多个处理器上同时运行,从而有可能加快计算速度。
尽管我们还可以实现多个进程的同时计算,但是线程的启动速度比进程快,并且线程使用共享内存进行互通通常比进程通过网络连接等通道进行通信更容易和/或者更有效。或者管道。
显示每个进程的线程
我们可以使用多种命令和方法来显示每个进程的线程并在Linux中对线程进行计数。
1.使用PID任务
我们可以使用/proc/<PID>/task /
中的可用子目录列表来计数线程。这部分内部的可用子目录总数与提供的PID的每个进程的线程数成正比。
例如,检查Java线程数,我有一个Java进程,可以看到我有多个子目录,因此这意味着它是一个多线程进程。
在此路径下使用ls
命令,我们可以显示每个进程的Java线程
# ls /proc/$(pidof java)/task/ 31161 31170 31175 31180 31185 31266 31274 31285 31290 31295 31301 31307 31165 31171 31176 31181 31186 31267 31276 31286 31291 31296 31302 31308 31167 31172 31177 31182 31241 31268 31279 31287 31292 31298 31303 38715 31168 31173 31178 31183 31260 31270 31283 31288 31293 31299 31304 42883 31169 31174 31179 31184 31265 31272 31284 31289 31294 31300 31306 47335
但是话又说回来,我还有另一个进程,如我们所见,我有单个子目录,因此我们知道这是一个单线程进程
# ls /proc/$(pgrep amsHelper)/task/ 6164
2.使用ps命令
我们也可以使用ps命令显示每个进程的线程。使用ps,我们可以列出LWP(轻量级进程),该进程描述相应进程的线程ID和" NWLP"(线程数)。
要使用" ps"命令显示每个进程的线程,可以使用以下参数
-L Show threads, possibly with LWP and NLWP columns. -e Select all processes -f Do full-format listing
例如:
# ps -eLf | less UID PID PPID LWP C NLWP STIME TTY TIME CMD root 1 0 1 0 1 Nov08 ? 00:01:48 /usr/lib/systemd/systemd --switched-root --system --deserialize 22 root 2 0 2 0 1 Nov08 ? 00:00:00 [kthreadd] root 4 2 4 0 1 Nov08 ? 00:00:00 [kworker/0:0H] root 6 2 6 0 1 Nov08 ? 00:00:04 [ksoftirqd/0] root 7 2 7 0 1 Nov08 ? 00:00:00 [migration/0] <<Output trimmed>>
3.使用pstree命令
我们还可以使用pstree来显示每个进程的线程。其中:我们可以看到Java线程计数并检查Java进程的线程数
# pstree -pau -l -G -s 31161 systemd,1 --switched-root --system --deserialize 22 mqdtomcat-wdg,31160,watchdog /usr/bin/dtomcat-wdg start mqjava,31161 -Xms300m -Xmx300m -XX:-UseLargePages -classpath /usr/share/tomcat/bin/bootstrap.jar:/usr/share/tomcat/bin/tomcat-juli.jar:/usr/share/java/commons-daemon.jar:/opt/watchdog/tomcat/lib/onends-tomcat.jar -Dcatalina.base=/opt/watchdog/tomcat -Dcatalina.home=/usr/share/tomcat -Djava.endorsed.dirs= -Djava.io.tmpdir=/opt/watchdog/tomcat/temp -Djava.util.logging.config.file=/opt/watchdog/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager org.apache.catalina.startup.Bootstrap start tq{java},31165 tq{java},31167 tq{java},31168 tq{java},31169 tq{java},31170 tq{java},31171 tq{java},31172 <<Output trimmed>>
4.使用top命令
在top
中,默认情况下,我们将无法看到每个进程的线程数。但是当运行top
时,可以更改要显示的字段,并添加此列以打印可以手动添加的每个进程的线程数。
按
f
这将显示top可以显示的字段列表。以粗体显示的字段是顶部将显示的字段。
使用向下箭头导航至nTH(线程数)。
按选择nTH
按"
s
对线程数进行排序。按" q"显示线程数数据。
接下来,我们应该在" top"命令的末尾看到一个新列,其中包含线程数(nTH)列,以显示每个进程的线程数
top - 15:24:41 up 2 days, 19:31, 2 users, load average: 0.46, 0.52, 0.52 Tasks: 219 total, 1 running, 218 sleeping, 0 stopped, 0 zombie %Cpu(s): 0.0 us, 0.0 sy, 0.0 ni, 99.9 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem : 13199273+total, 12801261+free, 1678324 used, 2301800 buff/cache KiB Swap: 4189180 total, 4189180 free, 0 used. 12937532+avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND nTH 9 root 20 0 0 0 0 S 0.3 0.0 5:17.22 rcu_sched 1 6357 ssrun 20 0 5310412 156988 13344 S 0.3 0.1 3:59.69 jsvc 52 51240 root 20 0 168472 2448 1628 R 0.3 0.0 0:00.04 top 1 1 root 20 0 193420 6408 2652 S 0.0 0.0 1:48.68 systemd 1 2 root 20 0 0 0 0 S 0.0 0.0 0:00.22 kthreadd 1 4 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H 1
检查每个进程的线程数
接下来,我们可以使用上面解释的命令,通过对它们进行一点自定义来"检查每个进程的线程数"。
1.使用PID状态
要检查每个进程的线程数,可以使用以下命令。例如,这里的Java线程数在我的Linux环境中为59个线程
# cat /proc/$(pgrep java)/status | grep -i Threads Threads: 59
虽然amsHelper
进程具有单线程
# cat /proc/$(pgrep amsHelper)/status | grep -i Threads Threads: 1
2.使用ps命令
我们使用ps命令显示每个进程的线程并计数线程,还可以使用ps命令获取LWP和NLWP详细信息,当与wc结合使用时,我们可以计算每个进程的线程数。
要检查特定PID的每个进程的线程数,例如检查Java线程数,请执行以下操作:
# ps -eL -q 31161 | wc -l 61
检查Linux系统中允许的线程数?
Linux没有每个进程限制的单独线程,只是系统上进程总数的限制。
这个值控制可以使用fork()
创建的最大线程数。在初始化期间,内核会设置该值,以便即使创建了最大线程数
检查Linux系统可以允许的线程数
# cat /proc/sys/kernel/threads-max 35000
可以写入threads-max的最小线程数为20。可以写入常量threads-max的最大值由常量FUTEX_TID_MASK(0x3fffffff)
给出。如果将超出此范围的值写入threads-max,则会发生错误" EINVAL"。
默认值取决于内存大小。我们可以使用threads-max来检查Linux中允许的线程数。我们可以按如下所示增加每个进程限制的线程数:
#echo 100000 > /proc/sys/kernel/threads-max
重要的提示:
将对照可用的RAM页面检查写入的值。如果线程结构将占用过多的可用RAM页(超过1/8),则会相应地减少thread-max。
单个用户可以创建的进程数(因此是线程数)也受到限制,有关这些限制的详细信息,请参见" ulimit":
# ulimit -a | grep -i processes max user processes (-u) 10000
其中:系统总共可以创建35,000个线程/进程,一个用户可以创建10000个进程。
逻辑很简单,这里每个CPU一次可以执行1个进程,如果有8个内核,这意味着一次可以轻松执行8到10个进程而没有任何压力,但是如果每个CPU的运行或者可运行线程数急剧增加,会有性能问题。
Linux中允许的最大进程数是多少?
在实时生产环境中,始终建议为我们开发的每个脚本或者工具也创建并发布手册页。
/proc/sys/kernel/pid_max (since Linux 2.5.34) This file specifies the value at which PIDs wrap around (i.e., the value in this file is one greater than the maximum PID). PIDs greater than this value are not allocated; thus, the value in this file also acts as a system-wide limit on the total number of processes and threads. The default value for this file, 32768, results in the same range of PIDs as on ear‐ lier kernels.
验证`kernel.pid_max'的值
[root@server1 ~]# sysctl -a | grep kernel.pid_max kernel.pid_max = 35000
其中:我可以在我的系统中同时执行35,000个进程,这些进程可以在单独的内存空间中运行。
要将kernel.pid_max
的值更改为65534:
# echo kernel.pid_max = 65534 >> /etc/sysctl.conf # sysctl -p