1 进程与程序
在Linux系统中,执行一个程序或命令就可以触发一个进程,系统会给予这个进程一个ID,称为PID,同时根据触发这个进程的用户与相关属性关系,基于这个PID一组有效的权限设置。如下图所示(图片来自《鸟哥的Linux私房菜》[1]):
举个常见的例子,我们要操作系统的时候通常是利用ssh连接程序或直接在主机上登录,然后获取shell。默认的shell是bash,对应的路径为/bin/bash
,那么同时间的每个人登录都是执行/bin/bash
,不过每个人获取的权限不同,如下图所示:
也就是说,当我们的登录并执行/bin/bash
程序时,系统已经给了我们一个PID,这个PID就是根据登陆者的UID/GID(/etc/passwd
)而来,而所谓用户的权限就是这个bash进程的权限。当这个进程执行其它作业时,比如我们在shell中执行touch
命令时,这个进程触发出来的其它进程也会沿用这个进程的相关权限。
我们对程序与进程做一个总结:
- 程序(program):通常为二进制程序,存储在存储媒介中(如磁盘等),以物理文件的形式存在。
- 进程(process):程序被触发后,执行者的权限与属性、程序的代码与所需数据等都会被加载到内存中,操作系统给予这个内存中的单元一个标识符(PID),可以说进程就是一个正在运行中的程序。
进程彼此之间是有关系的。从下图来看,连续执行两个bash后,第二个bash的父进程就是前一个bash,通过Parent PID(PPID)可获取其父进程的PID:
此外,子进程可以获取父进程的环境变量。
下面这个例子我们会展示子进程和父进程的关系。我们在当前的bash环境下,再触发一次bash,并用ps -l
命令查看进程相关的输出信息,
bash-3.2$ ps -l
UID PID PPID F CPU PRI NI SZ RSS WCHAN S ADDR TTY TIME CMD
501 9892 9827 4006 0 31 0 408650672 1968 - S 0 ttys001 0:00.01 /bin/bash
501 9905 9892 4006 0 31 0 408657840 2736 - S 0 ttys001 0:00.01 /bin/bash
可以看到第一个bash的PID和第二个bash的PPID都是9892,这是因为第二个bash是来自第一个所产生的。
很多常常会发现,“咦,我们们将有问题的进程关闭了(比如Ctrl+C
杀掉),怎么过一阵子它又自动产生了?而且新产生进程的PID还与原先不同这是怎么回事呢?”如果不是crontab计划任务的影响,那么肯定有一个父进程存在,所以我们杀掉子进程后,父进程又会主动再生成一个。那怎么办呢?“擒贼先擒王”。我们用ps auxf
找出那个父进程,然后将它杀掉即可(后文会提到)。
fork and exec:进程调用的流程
子进程和父进程之间的关系比较复杂,最大的复杂点在于进程之间的调用。Linux程序的调用通常称为fork-and-exec流程。进程都会借由父进程以复制(fork)的方式产生一个一模一样的子进程,然后被复制出来的子进程再以exec的方式来执行时机要执行的代码,最终就成为一个子进程。整个流程有点像下面这张图:
- 系统先以fork的方式复制一个与父进程相同的临时进程,这个进程与父进程唯一的差别就是PID不同,但这个临时进程还