实现我自己的ps命令

Mic*_*ael 1 c linux system-calls ps procfs

我正在尝试实现我自己的ps命令,称为psmod.我可以使用linux系统调用和/proc目录的所有实用程序.

我发现目录中的所有目录都/proc以数字作为名称,是系统中的进程.我的问题是:如何只选择那些在psmod被调用时处于活动状态的进程?我知道/proc/<pid>/stat有一封信代表了这个过程的现状; 无论如何,对于每一个进程来说/proc,这封信就是S在睡觉.

我还试图向每个进程发送一个信号0,从0到maximumnumberofprocesses(在我的例子中,32768),但是这样它发现的进程远远多于进程中的进程/proc.

所以,我的问题是,ps工作怎么样?源码对我来说有点复杂,所以如果有人能解释我,我将不胜感激.

osg*_*sgx 6

ps如何工作?

学习标准工具的方法是检查他们的源代码.有几种实现ps:procps和busybox; 而busybox更小,从它开始会更容易.ps来自busybox的来源:http: //code.metager.de/source/xref/busybox/procps/.主循环来自ps.c:

632 p = NULL;
633 while ((p = procps_scan(p, need_flags)) != NULL) {
634     format_process(p);
635 }
Run Code Online (Sandbox Code Playgroud)

实现procps_scanprocps.c(ENABLE_FEATURE_SHOW_THREADS首次忽略来自ifdefs 内部的代码).首先调用它将/proc使用alloc_procps_scan()以下命令打开目录:

290     sp = alloc_procps_scan();

100 sp->dir = xopendir("/proc");
Run Code Online (Sandbox Code Playgroud)

然后procps_scan将从/proc目录中读取下一个条目:

292 for (;;) {
310     entry = readdir(sp->dir);
Run Code Online (Sandbox Code Playgroud)

从子目录名解析pid:

316     pid = bb_strtou(entry->d_name, NULL, 10);
Run Code Online (Sandbox Code Playgroud)

并阅读/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);
Run Code Online (Sandbox Code Playgroud)

实际的无条件打印是format_process,ps.c.

因此,busybox的简单ps将读取所有进程的数据,并将打印所有进程(如果有-T选项,则打印所有进程和所有线程).

如何在调用psmod时仅选择那些处于活动状态的进程?

什么是"活跃"?如果要查找存在的所有进程,请执行readdir /proc.如果您只想找到非睡眠,请完整阅读/proc,检查每个过程的状态并仅打印非睡眠状态.该/procFS是虚拟的,是它相当快.

PS:例如,普通ps程序只打印当前终端的进程,通常是两个:

$ ps
  PID TTY          TIME CMD
 7925 pts/13   00:00:00 bash
 7940 pts/13   00:00:00 ps
Run Code Online (Sandbox Code Playgroud)

但我们可以用strace它,strace -ttt -o ps.log ps我看到它ps确实读取每个进程目录,文件statstatus.并且所需的时间(-ttstrace的选项给我们每个系统调用的时间戳):XX.719011 - XX.870349或仅在strace下120毫秒(这会减慢所有系统调用).根据time ps(我总共有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
Run Code Online (Sandbox Code Playgroud)