如何知道Puma中活动线程的数量

18

我想要查看服务器上活跃的Puma线程数量。

我无法通过 ps 看到它:

$ ps aux | grep puma
healthd   2623  0.0  1.8 683168 37700 ?        Ssl  May02   5:38 puma 2.11.1 (tcp://127.0.0.1:22221) [healthd]  
root      8029  0.0  0.1 110460  2184 pts/0    S+   06:34   0:00 grep --color=auto puma
root     18084  0.0  0.1  56836  2664 ?        Ss   May05   0:00 su -s /bin/bash -c puma -C /opt/elasticbeanstalk/support/conf/pumaconf.rb webapp
webapp   18113  0.0  0.8  83280 17324 ?        Ssl  May05   0:04 puma 2.16.0 (unix:///var/run/puma/my_app.sock) [/]                                                               
webapp   18116  3.5  6.2 784992 128924 ?       Sl   May05 182:35 puma: cluster worker 0: 18113 [/] 

就我目前的配置而言:

threads 8, 32

我本以为会看到至少8个美洲狮的帖子?


你找到解决方案了吗? - knagode
1
@knagode,我已经为这个问题开了一个悬赏,并且得到了很多关注,你能否检查答案并投票选择你认为更有帮助的答案?这将有助于我选择有效的答案。 - fguillen
6个回答

17

快速回答这个问题,可以使用以下方法获取正在运行给定PID的进程使用的线程数:

% ps -h -o nlwp <pid>

这将仅返回进程使用的线程总数。选项-h删除头文件,选项-o nlwp格式化ps的输出,以便仅输出轻量级进程数量(NLWP)或线程。例如,当只运行单个进程puma并且使用pgrep获得其PID时,您会得到:

% ps -h -o nlwp $(pgrep puma)
   4

进程、线程和轻量级进程有什么区别?

这个问题已经在各个地方得到了回答 [见这里这里优秀的geekstuff文章]。简而言之:

  • 进程本质上是程序的任何运行实例。

  • 线程是进程的执行流。包含多个执行流的进程称为多线程进程,并在其线程(内存、打开文件、io等)之间共享资源。Linux内核不知道线程是什么,只知道进程。过去,多线程处理在用户级别上处理而不是内核级别上处理。这使得内核难以进行适当的进程管理。

  • 引入轻量级进程(LWP)。这基本上是解决线程问题的答案。每个线程在内核级别被认为是一个LWP。进程和LWP之间的主要区别在于LWP共享资源。换句话说,轻量级进程是内核术语,用户称之为线程

ps可以显示有关线程或LWP的信息吗?

ps命令或进程状态命令提供有关当前运行进程及其相应LWP或线程的信息。为此,它利用/proc目录,这是一个虚拟文件系统,被认为是内核的控制和信息中心。[见这里这里]。

默认情况下,ps不会给您任何关于LWP的信息,但是在命令中添加选项-L-m通常可以解决问题。

man ps :: THREAD DISPLAY

   H      Show threads as if they were processes.
   -L     Show threads, possibly with LWP and NLWP columns.
   m      Show threads after processes.
   -m     Show threads after processes.
   -T     Show threads, possibly with SPID column.

针对进程 puma,其进程ID为 pgrep puma

% ps -fL $(pgrep puma)
UID        PID  PPID   LWP  C NLWP STIME TTY      STAT   TIME CMD
kvantour  2160  2876  2160  0    4 15:22 pts/39   Sl+    0:00 ./puma
kvantour  2160  2876  2161 99    4 15:22 pts/39   Rl+    0:14 ./puma
kvantour  2160  2876  2162 99    4 15:22 pts/39   Rl+    0:14 ./puma
kvantour  2160  2876  2163 99    4 15:22 pts/39   Rl+    0:14 ./puma

然而,加上-m选项会清晰地给出更好的概述。当多个进程使用相同的名称运行时,这尤其方便。
% ps -fmL $(pgrep puma)
UID        PID  PPID   LWP  C NLWP STIME TTY      STAT   TIME CMD
kvantour  2160  2876     -  0    4 15:22 pts/39   -      0:44 ./puma
kvantour     -     -  2160  0    - 15:22 -        Sl+    0:00 -     
kvantour     -     -  2161 99    - 15:22 -        Rl+    0:14 -     
kvantour     -     -  2162 99    - 15:22 -        Rl+    0:14 -     
kvantour     -     -  2163 99    - 15:22 -        Rl+    0:14 -     

在这个例子中,您可以看到进程puma的PID为2160,运行了4个线程(NLWP),ID为2160-2163。在STAT下面,您可以看到两个不同的值Sl+和'Rl+'。这里的lmulti-threaded的指示器。SR分别代表可中断休眠(等待事件完成)运行。因此,我们可以看到4个线程中有3个正在以99%的CPU运行,另一个线程正在睡眠。
您还可以直接使用格式说明符-o-O来获取信息。同时您也可以看到总累计CPU时间为44秒,而单个线程只运行了14秒。

man ps :: STANDARD FORMAT SPECIFIERS

   lwp    lightweight process (thread) ID of the dispatchable
          entity (alias spid, tid).  See tid for additional
          information.  Show threads as if they were processes.
   nlwp   number of lwps (threads) in the process.  (alias thcount).

所以您可以使用任何一个lwpspidtidnlwpthcount

如果您只想获取名为puma的进程的线程数,您可以使用:

% ps -o nlwp $(pgrep puma)
NLWP
   4

或者如果您不喜欢标题。
% ps -h -o nlwp $(pgrep puma)
   4

您可以使用以下方法获取更多信息:

% ps -O nlwp $(pgrep puma)
PID   NLWP S TTY          TIME COMMAND
19304    4 T pts/39   00:00:00 ./puma

最后,您可以将标志与ps aux组合以列出线程。
 % ps aux -L
USER       PID   LWP %CPU NLWP %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
...
kvantour  1618  1618  0.0    4  0.0  33260  1436 pts/39   Sl+  15:17   0:00 ./puma
kvantour  1618  1619 99.8    4  0.0  33260  1436 pts/39   Rl+  15:17   0:14 ./puma
kvantour  1618  1620 99.8    4  0.0  33260  1436 pts/39   Rl+  15:17   0:14 ./puma
kvantour  1618  1621 99.8    4  0.0  33260  1436 pts/39   Rl+  15:17   0:14 ./puma
...

top是否可以显示有关线程或LWP的信息?

top有一个选项可以通过在交互模式下按下H或使用top -H启动来显示线程。问题是它将线程列为进程(类似于ps -fH)。

% top
top - 09:42:10 up 17 days, 3 min,  1 user,  load average: 3.35, 3.33, 2.75
Tasks: 353 total,   3 running, 347 sleeping,   3 stopped,   0 zombie
%Cpu(s): 75.5 us,  0.6 sy,  0.5 ni, 22.6 id,  0.0 wa,  0.0 hi,  0.8 si,  0.0 st
KiB Mem : 16310772 total,  8082152 free,  3662436 used,  4566184 buff/cache
KiB Swap:  4194300 total,  4194300 free,        0 used. 11363832 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
  868 kvantour  20   0   33268   1436   1308 S 299.7  0.0  46:16.22 puma
 1163 root      20   0  920488 282524 258436 S   2.0  1.7 124:48.32 Xorg
 ...

在这里您可以看到,puma累计运行时间为46:16.22,CPU利用率约为300%。不过,并没有指示这是一个多线程进程。唯一的指示是CPU使用率,但是如果3个线程“睡眠”,这个值可能低于100%。此外,状态标志显示S,表示第一个线程正在休眠。按下H键会给出更多信息。

% top -H
top - 09:48:30 up 17 days, 10 min,  1 user,  load average: 3.18, 3.44, 3.02
Threads: 918 total,   5 running, 910 sleeping,   3 stopped,   0 zombie
%Cpu(s): 75.6 us,  0.2 sy,  0.1 ni, 23.9 id,  0.0 wa,  0.0 hi,  0.2 si,  0.0 st
KiB Mem : 16310772 total,  8062296 free,  3696164 used,  4552312 buff/cache
KiB Swap:  4194300 total,  4194300 free,        0 used. 11345440 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
  870 kvantour  20   0   33268   1436   1308 R 99.9  0.0  21:45.35 puma
  869 kvantour  20   0   33268   1436   1308 R 99.7  0.0  21:45.43 puma
  872 kvantour  20   0   33268   1436   1308 R 99.7  0.0  21:45.31 puma
 1163 root      20   0  920552 282288 258200 R  2.0  1.7 124:52.05 Xorg 
  ...

现在我们只看到了3个线程。由于其中一个线程正在“睡眠”,因此它在按CPU使用率排序时排在最下面。top为了查看所有线程,最好让其显示特定的pid(针对单个进程):
% top -H -p $(pgrep puma)
top - 09:52:48 up 17 days, 14 min,  1 user,  load average: 3.31, 3.38, 3.10
Threads:   4 total,   3 running,   1 sleeping,   0 stopped,   0 zombie
%Cpu(s): 75.5 us,  0.1 sy,  0.2 ni, 23.6 id,  0.0 wa,  0.0 hi,  0.7 si,  0.0 st
KiB Mem : 16310772 total,  8041048 free,  3706460 used,  4563264 buff/cache
KiB Swap:  4194300 total,  4194300 free,        0 used. 11325008 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
  869 kvantour  20   0   33268   1436   1308 R 99.9  0.0  26:03.37 puma
  870 kvantour  20   0   33268   1436   1308 R 99.9  0.0  26:03.30 puma
  872 kvantour  20   0   33268   1436   1308 R 99.9  0.0  26:03.22 puma
  868 kvantour  20   0   33268   1436   1308 S  0.0  0.0   0:00.00 puma

当你有多个进程运行时,你可能会想要按下"f"键并切换"PGRP"。这将显示进程的组PID。(在ps中的PID与top中的PID是LWP)。
如何在不使用"ps"或"top"的情况下获取线程计数?
文件"/proc/$PID/status"包含一行声明进程PID为"$PID"的线程数。
% grep Threads /proc/19304/status
Threads:        4

总体评论

  • 有可能您无法找到另一个用户的进程,因此无法获取该进程正在使用的线程数。这可能是由于 /proc/ 的挂载选项(hidepid=2)引起的。

使用的示例程序:

#include <omp.h>
#include <stdio.h>
#include <stdlib.h>

int main (int argc, char *argv[]) {
char c = 0;
#pragma omp parallel shared(c)   {
    int i = 0;
    if (omp_get_thread_num() == 0) {
      printf("Read character from input : ");
      c = getchar();
    } else {
      while (c == 0) i++;
      printf("Total sum is on thread %d : %d\n", omp_get_thread_num(), i);
    }
  }
}

使用gcc -o puma --openmp编译


6
如果您只是想查看进程生成的线程数,您可以查看位于/proc/[process-PID]/task下创建的task文件夹的数量,因为每个线程都会在此路径下创建一个文件夹。因此,计算文件夹数量就足够了。
实际上,ps实用程序本身就从此路径读取信息,一个名为/proc/[PID]/cmdline的文件以更易读的方式表示。
来自Linux文件系统层次结构

/proc非常特殊,因为它也是一个虚拟文件系统。它有时被称为进程信息伪文件系统。它不包含“真实”的文件,而是运行时系统信息(例如系统内存,已挂载的设备,硬件配置等)。因此,它可以被视为内核的控制和信息中心。实际上,相当多的系统实用程序只是对此目录中的文件的调用。

要获取进程puma的PID,只需使用ps或您选择的任何实用程序即可。
ps aux | awk '/[p]uma/{print $1}'

或者更直接地使用pidof(8) - Linux man page,它可以直接根据进程名称获取PID。

pidof -s puma

现在,您已经有了用于计算进程创建的task/文件夹数量的PID,请使用find命令。

find /proc/<PID>/task -maxdepth 1 -type d -print | wc -l

3

ps aux | grep puma 可以给你只包含puma进程的进程列表。你需要找出特定进程运行的线程数量。也许下面这条命令可以帮到你:

ps -T -p 2623

你需要提供进程id,以查找想要了解线程数的进程。确保提供准确的进程id。


1
使用pswc计算puma线程数:
ps --no-headers -T -C puma | wc -l

字符串 "puma" 可以按需替换。例如,计算 bash 线程的数量:
ps --no-headers -T -C bash | wc -l

在我的系统上,输出如下:
9

问题中的代码 ps aux | grep puma 存在一些与 grep 相关的问题:

  1. 它返回 grep --color=auto puma,这根本不是一个 puma 线程。
  2. 同样地,任何包含字符串 "puma" 的工具或命令,例如名为 notpuma 的工具,都将被 grep 匹配。

1
我发现 "htop" 是一个非常好的解决方案。只需切换到“树视图”,您就可以查看每个 puma-worker 和该 worker 下的线程。

1
每个工作者的Puma线程数:
ps aux | awk '/[p]uma/{print $2}' | xargs ps -h -o nlwp

示例输出:

   7
  59
  59
  61
  59
  60
  59
  59
  59

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接