Linux中的进程树:探究pstree源码 (linux pstree源码)
Linux作为一种开源操作系统,其独特的设计让人们拥有更多的选择和自由。在Linux中,进程是操作系统管理的最基本的单位,Linux操作系统中的所有工作都是通过进程完成的。为了有效地管理进程,Linux系统提供了许多用于查看和管理进程的工具,其中pstree是一个广泛使用的工具之一。本文将探究pstree的源码实现,帮助读者更好地了解它的工作原理。
一、什么是进程树?
在Linux系统中,进程不仅仅是一个简单的程序执行体,它还具有父子关系。例如,每个进程都有一个父进程(除了init进程)和子进程。Linux操作系统中的所有进程都可以形成一个进程树。进程树指的是一组相互关联的进程,这些进程之间是按照父子关系组成的。
二、什么是pstree?
pstree是一款Linux命令行工具,用于显示系统中所有进程以及它们的层次结构。它能够以树状结构的方式显示进程,显示进程之间的父子关系,清晰地显示进程之间的层次结构。pstree的使用方法非常简单,只需要在控制台中输入pstree命令,就会显示系统中所有进程的树状结构。
三、pstree的实现原理
1.主要函数
pstree的核心代码是由一个C函数实现的,该函数名为print_tree()函数,这个函数主要是通过递归的方式遍历整个进程树,并输出树形结构。 具体思路是:从进程根节点开始遍历,在遍历的过程中,递归遍历下一层的进程,从而输出整个进程树。print_tree()函数的代码如下所示:
void print_tree(pid_t pid, bool is_last) {
/* pid的信息通过获取/proc/pid/stat文件中的信息得到 */
ProcessInfo *pi = procstat_get_process_info(pid);
if (pi == NULL) {
return;
}
/* 输出每个进程的名称-指针的格式 */
printf(is_last ? “\\– ” : “|–“);
printf(“%s (%d)\n”, pi->name, (int)pid);
/* 递归 */
for (int i = 0; i n_children; i++) {
pid_t child_pid = pi->childrenpids[i];
/* 如果时最后一个进程则输出 ‘|’ */
print_tree(child_pid, i == pi->n_children – 1);
}
/* 释放内存 */
procstat_free_process_info(pi);
}
在该函数中,print_tree()函数是由pid_t pid和bool is_last两个参数调用的,pid用于确定需要遍历的进程,is_last参数用于记录是否是该层中的最后一个子进程,以便于显示不同的符号。
2.进程状态信息获取函数
在打印整个进程树的时候,需要获取每个进程的相关信息,这些信息主要包括进程ID、父进程ID、进程状态、进程优先级等。获取这些信息的方式是通过读取/proc/pid/stat文件的方式实现的。/proc/pid/stat文件中存储了进程的相关信息,包括进程ID、进程名称等,pstree通过读取该文件来获取进程的相关信息。获取进程的方法主要是由两个C函数实现的,分别是processinfo_get_process_info()函数和processinfo_free_process_info()函数。其中processinfo_get_process_info()函数用于获取进程信息,processinfo_free_process_info()函数用于释放进程信息的内存,避免内存泄漏。
四、pstree运行结果分析
下面是一个示例输出的结果,可以看到pstree以树形结构的形式展示系统中所有进程,并以不同的符号(“|”和“\”)表示各个进程之间的父子关系。
systemd─┬─ModemManager───2*[{ModemManager}]
├─NetworkManager─┬─dhcpd
│ ├─{NetworkManager}
│ └─2*[{NetworkManager}]
├─accounts-daemon───2*[{accounts-daemon}]
├─agetty
├─avahi-daemon───avahi-daemon
├─bluetoothd
├─colord───2*[{colord}]
├─cron
├─2*[dbus-daemon]
├─dnasq
├─gdm3─┬─gdm-session-wor─┬─Xorg───{Xorg}
│ │ ├─gnome-session-b─┬─gnome-shell─┬─ibus-daemon─┬─{ibus-daemon}
│ │ │ │ │ ├─{gnome-shell}
│ │ │ │ │ └─3*[{ibus-daemon}]
│ │ │ │ ├─gsd-sharing─┬─{gsd-sharing}
│ │ │ │ │ ├──3*[{gsd-sharing}]
│ │ │ │ │ └─2*[{gsd-sharing}]
│ │ │ │ ├─gsd-xset─┬─{gsd-xset}
│ │ │ │ │ └─2*[{gsd-xset}]
│ │ │ │ ├─gnome-shell-cal───2*[{gnome-shell-cal}]
│ │ │ │ ├─3*[{gnome-shell-b}]
│ │ │ │ ├─3*[{gdm-session-wor}]
│ │ │ │ └─3*[{gnome-session-b}]
│ │ │ ├─2*[ibus-x11───{ibus-x11}]
│ │ │ ├─nautilus-desktop─┬─{nautilus-desktop}
│ │ │ │ └─3*[{nautilus-desktop}]
│ │ │ └─3*[{gdm-session-wor}]
│ │ └─{gdm-session-wor}
│ └─2*[{gdm3}]
├─irqbalance───{irqbalance}
├─kerneloops───{kerneloops}
├─2*[kworker/0:0H]
├─2*[kworker/u2:0]
├─2*[migration/0]
├─2*[rcu_gp]
├─rcu_sched
├─rsyslogd───3*[{rsyslogd}]
├─rtkit-daemon───2*[{rtkit-daemon}]
├─artd───{artd}
├─systemd-journal
├─systemd-logind
├─systemd-timesyn───{systemd-timesyn}
├─thermald───{thermald}
└─udisksd───3*[{udisksd}]
从输出结果可以看出,pstree能够清晰地树形显示系统中的所有进程,每个进程都有其父子关系,能够方便地查看进程的层次结构,很方便地进行排错、分析和优化进程。同时,pstree还能根据进程的PID、名称、用户等排序输出结果,更加方便用户的使用。
进程是Linux操作系统中最基本的单位,而pstree是一款广泛使用的工具,能够清晰地树形显示系统中的所有进程。pstree的实现原理是通过遍历整个进程树,并以递归的方式输出树形结构。可以根据PID、名称、用户等不同的方式排序输出结果,更加方便用户进行进程的搜索和分析。本文对pstree的源码实现进行了探究,希望能够帮助读者更好地了解它的工作原理,并在实际操作中得到应用和优化。