Linux 中程序与进程关系

进程与程序

程序(Program)是可执行的二进制文件。

当触发执行程序动作后,程序内容及程序数据会加载到内存中,成为一个运行中的程序,即进程(Process)。

系统为这个进程分配一个 ID,称为 PID(Program ID)。同时,根据触发这个进程的用户及相关属性关系,为这个 PID 设置一组有效的权限。

子进程与父进程

登录系统后,会获得一个 bash 的 shell。通过 bash 提供的接口执行另一个命令,如 vim,它也会被分配一个 PID。此时,原本的 bash 就是 vim 的父进程。父进程的 PID 可以用 PPID(Parent ID)表示。

通常,子进程会继承父进程的相关权限和环境变量。

例如,在 bash 中执行 bash,再用 ps -l 命令查看:

[root@101c7 ~]$ bash
[root@101c7 ~]$ ps -l
F S   UID    PID   PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0   5713   5709  0  80   0 - 28920 do_wai pts/0    00:00:00 bash
4 S     0  35555   5713  0  80   0 - 28919 do_wai pts/0    00:00:00 bash
0 R     0  35570  35555  0  80   0 - 38332 -      pts/0    00:00:00 ps

可以看到第一个 bash 的 PID 5517 是第二个 bash 的 PPID。

过程调用的流程

父进程和子进程之间的互相调用过程通常称为 fork-and-exec 的流程。进程都会通过父进程以复制(fork)的方式产生一个一模一样的子进程,然后被复制的子进程再以 exec 的方式执行实际要进行的进程,最终成为一个子进程的存在。

其过程从上往下执行如下示意:

阶段 状态
父进程 PID=x,程序=a
中间暂存进程 PID=y,程序=a,PPID=x
子进程 PID=y,程序=b,PPID=x

内部程序沟通

在系统内,许多进程需要互相交换信息。除了通过文件进行沟通,还包括共享内存(Shared Memory)、消息队列(Message Queues)、管道(Pipe)等方式,统称为内部程序沟通(Inter-Process Communication)。可以用命令 ipcs 观察沟通状态:

[root@server1 ~]$ ipcs

 Message Queues 
key        msqid      owner      perms      used-bytes   messages    

 Shared Memory Segments 
key        shmid      owner      perms      bytes      nattch     status      

 Semaphore Arrays 
key        semid      owner      perms      nsems   

可以通过 ipcrm 命令将看到的 interprocess 删除。

多用户与多任务环境

多用户系统也叫分时系统(Time-Share System),指多个用户可以在同一时间使用计算机系统。与 Linux 相比,Windows 系统是单用户系统。

多任务是指 Linux 可以同时执行几个任务,它可以在还未执行完一个任务时又执行另一项任务。

每个用户权限不同,所以登录后获得的 shell 的 PID 不同。而 CPU 速度 1GHz 代表 CPU 每秒可以运行 109次命令,每个工作都占用 CPU 的几个命令次数。Linux 可以让 CPU 在各个进程间进行切换。所以实际上,所谓多任务处理是 CPU 快速地执行多个任务,看上去就像它们同时被执行一样。CPU 切换进程的工作与这些工作进入到 CPU 运行的调度会影响到系统的整体性能。由于 CPU 性能出众,所以可以支持多个用户同时登录运行不同程序,这就是多用户与多任务环境。

僵尸进程

造成僵尸进程的原因是该进程应该已经执行完毕或因故应该要终止时,该进程的父进程很可能已经死亡,无法完整将该进程结束掉,而造成那个进程一直滞留在内存。

使用 ps 命令查看进程时,如果发现某个进程的 CMD 后面有 <defunct>,就代表该进程是僵尸进程。