我正在尝试实现自己的ps
命令,名为psmod
。
我可以使用linux系统调用和/proc
目录的所有实用程序。
我发现/proc
目录中的所有目录都有一个数字作为系统中的进程。我的问题是:如何在调用psmod
时仅选择那些处于活动状态的进程?
我知道在/proc/<pid>/stat
中有一封信代表了这个过程的现状;无论如何,对于/proc
中的每个进程,这封信都是S
,正在睡觉。
我还尝试向每个进程发送一个信号0,从0到maximumnumberofprocesses
(在我的情况下,32768),但是这样它发现的进程远远多于{{1}中出现的进程。 }。
所以,我的问题是,/proc
如何运作?源码对我来说有点复杂,所以如果有人能解释我,我将不胜感激。
答案 0 :(得分:6)
ps如何运作?
学习标准工具的方法 - 检查他们的源代码。 ps
:procps
和busybox有多种实现方式;而busybox更小,从它开始会更容易。来自busybox的ps
来源:http://code.metager.de/source/xref/busybox/procps/。主loop from ps.c
:
632 p = NULL;
633 while ((p = procps_scan(p, need_flags)) != NULL) {
634 format_process(p);
635 }
procps_scan
的实施位于procps.c
(第一次忽略来自ENABLE_FEATURE_SHOW_THREADS
ifdef内部的代码)。首次调用它将使用/proc
打开alloc_procps_scan()
目录:
290 sp = alloc_procps_scan();
100 sp->dir = xopendir("/proc");
然后procps_scan
将读取/proc
目录中的下一个条目:
292 for (;;) {
310 entry = readdir(sp->dir);
从子目录名解析pid:
316 pid = bb_strtou(entry->d_name, NULL, 10);
并阅读/prod/pid/stat
:
366 /* These are all retrieved from proc/NN/stat in one go: */
379 /* see proc(5) for some details on this */
380 strcpy(filename_tail, "stat");
381 n = read_to_buf(filename, buf);
实际无条件打印位于format_process
, ps.c
。
因此,busybox的简单ps将读取所有进程的数据,并将打印所有进程(如果有-T
选项,则打印所有进程和所有线程。)
如何只调用那些在调用psmod时处于活动状态的进程?
什么是&#34;活跃&#34;?如果要查找存在的所有进程,请执行/proc
的readdir。如果您只想找到非睡眠状态,请完整阅读/proc
,检查每个进程的状态并仅打印非睡眠状态。 /proc
fs是虚拟的,而且速度相当快。
PS:例如,普通ps
程序只打印当前终端的进程,通常是两个:
$ ps
PID TTY TIME CMD
7925 pts/13 00:00:00 bash
7940 pts/13 00:00:00 ps
但我们可以strace
strace -ttt -o ps.log ps
ps
,我看到stat
确实读取了每个进程目录,文件status
和-tt
。并且所需的时间(选项time ps
strace给出了每个系统调用的时间戳):XX.719011 - XX.870349或仅在strace下120毫秒(这会减慢所有系统调用)。根据{{1}}(我总共有250个进程),现实生活中只需要20毫秒:
$ time ps
PID TTY TIME CMD
7925 pts/13 00:00:00 bash
7971 pts/13 00:00:00 ps
real 0m0.021s
user 0m0.006s
sys 0m0.014s
答案 1 :(得分:-3)
“我的问题是:如何只选择那些在调用psmod时处于活动状态的进程?”
我希望这个命令可以帮到你:
top -n 1 | awk“NR&gt; 7”| awk {'print $ 1,$ 8,$ 12'} | grep R
我在ubuntu 12上。