典型进程的ID及其功能

ID

进程名

中文名

类型

作用

0

swapper

交换进程

系统进程

它是内核⼀一部分,不执⾏行磁盘上的程序,是调度进程。

1

init

init进程

用户进程

永远不会终⽌止,启动系统,读取系统初始化的文件。

2

pagedaemon

页精灵进程

系统进程

虚存系统的请页操作

实际用户和有效用户

  实际用户ID/实际组ID标识进程究竟是谁(即是进程在系统的唯⼀一标识),有效用户ID/有效组ID/附加组ID决定了进程的访问权限

子进程的创建

  1. 子进程获得父进程数据空间、堆和栈的副本(主要是数据结构的副本)。父子进程不共享这些存储空间部分。父子进程共享正文段。由于fork之后经常归属exec,所以现在很多实现并不执行一个父进程数据段、栈和堆的完全复制。作为替代,使用了写时复制(Copy-On-Write)技术。这些区域由父子进程共享,而且内核将他们的访问权限改变为只读的。如果父子进程中的任一个试图修改这些区域,则内核只为修改区域的那块内存制作一个副本。
  2. 父子进程之间的区别
  1. 父子相同处:
    全局变量、.data、.text、栈、堆、环境变量、用户ID、宿主目录、进程工作目录、信号处理方式…
  2. 父子不同处:
    1.进程ID
    2.fork返回值 //给子进程返回0给父进程返回子进程的pid
    3.父进程ID
    4.进程运行时间
    5.闹钟(定时器)
    6.未决信号集
  1. vfork与fork的区别
    vfork在子进程调用exec或exit之前,它在父进程的空间中运行,也就是说会更改⽗父进程的数据段、栈和堆。vfork和fork另⼀一区别在:vfork保证子进程先运行,在它调用exec或(exit)之后⽗父进程才可能被调度运行。

exec函数簇

exec函数族一般规律
exec函数一旦调用成功即执行新的程序,不返回。只有失败才返回,错误值-1。所以通常我们直接在exec函数调用后直接调用perror()和exit(),无需if判断。

l (list)

命令行参数列表

p (path)

搜素file时使用path变量

v (vector)

使用命令行参数数组

e (environment)

使用环境变量数组,不使用进程原有的环境变量,设置新加载程序运行的环境变量

事实上,只有execve是真正的系统调用,其它五个函数最终都调用execve,所以execve在man手册第2节,其它函数在man手册第3节。这些函数之间的关系如下图所示。

linux复习之进程基础知识_子进程

孤儿进程

孤儿进程: 父进程先于子进程结束,则子进程成为孤儿进程,子进程的父进程成为init进程,称为init进程领养孤儿进程。

僵尸进程

僵尸进程: 进程终止,父进程尚未回收,子进程残留资源(PCB)存放于内核中,变成僵尸(Zombie)进程。

wait函数

  一个进程在终止时会关闭所有文件描述符,释放在用户空间分配的内存,但它的PCB还保留着,内核在其中保存了一些信息:如果是正常终止则保存着退出状态,如果是异常终止则保存着导致该进程终止的信号是哪个。这个进程的父进程可以调用wait或waitpid获取这些信息,然后彻底清除掉这个进程。我们知道一个进程的退出状态可以在Shell中用特殊变量$?查看,因为Shell是它的父进程,当它终止时Shell调用wait或waitpid得到它的退出状态同时彻底清除掉这个进程。
父进程调用wait函数可以回收子进程终止信息。该函数有三个功能:
  ① 阻塞等待子进程退出
  ② 回收子进程残留资源
  ③ 获取子进程结束状态(退出原因)。
pid_t wait(int *status); 成功:清理掉的子进程ID;失败:-1 (没有子进程)
  当进程终止时,操作系统的隐式回收机制会:1.关闭所有文件描述符 2. 释放用户空间分配的内存。内核的PCB仍存在。其中保存该进程的退出状态。(正常终止→退出值;异常终止→终止信号)
  可使用wait函数传出参数status来保存进程的退出状态。借助宏函数来进一步判断进程终止的具体原因。宏函数可分为如下三组:

  1. WIFEXITED(status) 为非0 → 进程正常结束
    WEXITSTATUS(status) 如上宏为真,使用此宏 → 获取进程退出状态 (exit的参数)
  2. WIFSIGNALED(status) 为非0 → 进程异常终止
    WTERMSIG(status) 如上宏为真,使用此宏 → 取得使进程终止的那个信号的编号。
    *3. WIFSTOPPED(status) 为非0 → 进程处于暂停状态
    WSTOPSIG(status) 如上宏为真,使用此宏 → 取得使进程暂停的那个信号的编号。
    WIFCONTINUED(status) 为真 → 进程暂停后已经继续运行
    【wait1.c、wait2.c】

waitpid函数

作用同wait,但可指定pid进程清理,可以不阻塞。
pid_t waitpid(pid_t pid, int *status, in options); 成功:返回清理掉的子进程ID;失败:-1(无子进程)
特殊参数和返回情况:
参数pid:

0 回收指定ID的子进程
-1 回收任意子进程(相当于wait)
0 回收和当前调用waitpid一个组的所有子进程
< -1 回收指定进程组内的任意子进程
返回0:参3为WNOHANG,且子进程正在运行。

注意:一次wait或waitpid调用只能清理一个子进程,清理多个子进程应使用循环。