检查Linux中每个进程(线程与进程)的线程数

时间:2020-01-09 10:37:40  来源:igfitidea点击:

在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