Linux内核进程管理子系统有什么第八回 —— 进程主结构详解(4)
接前一篇文章:Linux内核进程管理子系统有什么第七回 —— 进程主结构详解(3)
本文内容参考:
Linux内核进程管理专题报告_linux rseq-CSDN博客
《趣谈Linux操作系统 核心原理篇:第三部分 进程管理》—— 刘超
《图解Linux内核 基于6.x》 —— 姜亚华 机械工业出版社
ps指令详解 - 苦咖啡~~ - 博客园
Linux ps命令详解-CSDN博客
linux常用命令详解_ps -elf-CSDN博客
特此致谢!
进程管理核心结构 —— task_struct
1. 任务ID相关成员
上一回讲到了struct task_struct中任务ID相关的成员。包括:
pid_t pid;pid_t tgid;struct task_struct *group_leader;struct list_head thread_group;
给出了一个例程,结合此例程,可以更好地理解这些成员的含义。
上一回在一个终端下运行例程、另一个终端下执行命令:
ps -eLo pid,ppid,pgid,sid,lwp,nlwp,comm | grep process_test
的最终结果如下:
$ ps -eLo pid,ppid,pgid,sid,lwp,nlwp,comm | grep process_test765335 764210 765335 764210 765335 1 process_test765336 765335 765335 764210 765336 3 process_test765336 765335 765335 764210 765337 3 process_test765336 765335 765335 764210 765338 3 process_test
在这里先看一下ps -eLo这个命令的含义,在实际工作中经常会用到ps命令与系统和内核打交道。在此要对于ps命令进行知识补强。
知识补强 —— ps命令
在Linux系统中,ps是一个简单而强大的进程查看命令,用于查看进程状态。它提供了丰富的选项和参数,允许用户以不同的方式显示进程信息。其中最为常用的是ps -ef和ps aux。
- ps -aux
ps -aux是以BSD方式显示系统上的全部进程。
a —— 显示所有用户的进程。
u —— 显示进程的用户/拥有者。
x —— 显示无控制终端的进程。
执行ps -aux命令后,结果示例如下:
$ps -aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 4828 516 ? Ss 2014 1:28 init [3]
root 2 0.0 0.0 0 0 ? S 2014 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? S 2014 0:43 [migration/0]
root 4 0.0 0.0 0 0 ? S 2014 7:34 [ksoftirqd/0]
root 5 0.0 0.0 0 0 ? S 2014 0:01 [migration/0]
root 6 0.0 0.0 0 0 ? S 2014 0:03 [watchdog/0]
root 7 0.0 0.0 0 0 ? S 2014 3:04 [migration/1]
root 8 0.0 0.0 0 0 ? S 2014 0:01 [migration/1]
root 9 0.0 0.0 0 0 ? S 2014 1:44 [ksoftirqd/1]
root 10 0.0 0.0 0 0 ? S 2014 0:01 [watchdog/1]
root 11 0.0 0.0 0 0 ? S 2014 2:21 [migration/2]
root 12 0.0 0.0 0 0 ? S 2014 0:01 [migration/2]
- ps -ef
ps -ef是以System V方式显示系统上的全部进程。该种方式比BSD方式显示的内容更多。
e —— 显示所有用户的进程,此参数的效果与指定"a"参数相同。
f —— 用ASCII字符显示树状结构,表达程序间的相互关系。
执行ps -ef命令后,结果示例如下:
$ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 2014 ? 00:01:28 init [3]
root 2 0 0 2014 ? 00:00:00 [kthreadd]
root 3 2 0 2014 ? 00:00:43 [migration/0]
root 4 2 0 2014 ? 00:07:34 [ksoftirqd/0]
root 5 2 0 2014 ? 00:00:01 [migration/0]
root 6 2 0 2014 ? 00:00:03 [watchdog/0]
root 7 2 0 2014 ? 00:03:04 [migration/1]
root 8 2 0 2014 ? 00:00:01 [migration/1]
root 9 2 0 2014 ? 00:01:44 [ksoftirqd/1]
root 10 2 0 2014 ? 00:00:01 [watchdog/1]
root 11 2 0 2014 ? 00:02:21 [migration/2]
root 12 2 0 2014 ? 00:00:01 [migration/2]
- ps -eLo
本例中并没有使用ps -aux或ps -ef,而是ps -eLo。选项-e的作用上边已经给出了,这里给出L和o的作用。
-L —— 打印出线程的ID和线程的个数。
-o —— 以用户自定义的格式输出。包括但不限于以下子选项:
"psr":表示当前分配给进程运行的处理器编号。
"lwp":表示线程的ID。
"ruser":表示运行进程的用户。
"pid":表示进程的ID。
"ppid ":表示父进程的ID。
"args":表示运行的命令行及其参数。
那么本例中的命令:
ps -eLo pid,ppid,pgid,sid,lwp,nlwp,comm | grep process_test
作用就是显示进程ID、父进程ID、进程组ID、会话(session)ID、线程ID等。详细的含义如下表所示:
PID | PPID | PGID | SID | LWP | NLWP | COMMAND |
---|---|---|---|---|---|---|
进程ID | 父进程ID | 进程组ID | 会话ID | 线程ID | 线程组的线程数 | 程序名 |
结合上一回实际的结果:
$ ps -eLo pid,ppid,pgid,sid,lwp,nlwp,comm | grep process_test765335 764210 765335 764210 765335 1 process_test765336 765335 765335 764210 765336 3 process_test765336 765335 765335 764210 765337 3 process_test765336 765335 765335 764210 765338 3 process_test
可以看到:
- 执行process_test的进程id为765335;
- fork得到的子进程的id为765336;
- 子进程创建的两个线程的进程id也是765336,但它们拥有不同的线程id(线程1是765337、线程2是765338)。实际上它们属于同一个线程组;
- 所有4个process_test相关的任务都属于同一个进程组,id为765335,765335为领导进程。
- 整个会话由bash创建,会话id为764210(上边结果中没有显示出来);
- 765336、765337、765338的进程id是相同的,都是765336;
- 进程id实际上等同于线程组id。同一个线程组内的线程,它们的进程id是相同的,等于领导进程的id。
- 对于一个单线程的进程而言(如765335),其线程id与进程id相等;对于一个多线程的进程而言,每个线程都有各自不同的线程id,但进程id是相同的。
更多内容请看下回。