第三章 Unix/Linux进程管理
3.1 多任务处理
一般来说,多任务处理指的是同时进行几项独立活动的能力。在计算机技术中,多任务处理指的是同时执行几个独立的任务。
在单处理器(单CPU)中,一次只能执行一个任务,多任务处理是通过在不同任务之间多路复用CPU的执行时间来实现的,即将CPU执行操作从一个任务切换到另一个任务。这种逻辑并行性被称为“并发”。
3.2 进程的概念
操作系统是一个多任务处理系统,任务也称为进程。
进程是对映像的执行
在一个单CPU系统中,一次只能执行一个进程。
3.3 多任务处理系统
多任务处理系统,简称MT
- type.h 文件定义了系统常熟和表示进程的简单PROC结构体
/*********** type.h file ************/
#define NPROC 9
#define SSIZE 1024
// PROC status
#define FREE 0
#define READY 1
#define SLEEP 2
#define ZOMBIE 3
typedef struct proc{
struct proc *next;
int *ksp;
int pid;
int status;
int priority;
int kstack [SSIZE];
}PROC;
- t.c文件定义MT系统数据结构、系统初始化代码和进程管理函数
- ts.s文件在32位GCC汇编代码中可实现进程上下文切换
3.4 进程同步
一个操作系统包含许多并发进程,这些进程可以彼此交互。进程同步是指控制和协调进程交互以确保其正确执行所需的各项和规则和机制。
-
睡眠模式
当某进程需要某些当前没有的东西时,它就会在某个事件值上进入休眠状态,该事件值表示休眠的原因。 -
唤醒模式
多个进程可能进入休眠状态等待同一个事件。在这种情况下,所有这些进程都将休眠等待同一个事件值。当某个等待实践发生时,另一个执行实体将会调用kwakeup(event),唤醒正处于休眠状态等待该事件值的所有程序。
kwakeup()的算法是:
3.5 进程终止
在操作系统中,进程可能终止或死亡。
- 正常终止:进程自行调用结束函数exit(value)进行终止。
- 异常终止:进程因为某个信号而异常终止。
1、kexit()的算法
在所有类Unix系统中,进程P1(又叫INIT进程)将所有其他的孤儿进程,不论死亡还是活跃都被送到P1中,称为P1的子进程。
INIT进程P1:有非常重要作用
它是除了P0之外所有进程的祖先,所有登录进程都是它的子进程。
它管理所有没有父进程的进程。(他就像孤儿院的院长,所有孤儿都叫他爸爸)。
它不停寻找僵尸进程,并终止他们(埋葬它们死亡的空壳)。
3、等待子进程终止
在任何时候,进程都可以调用内核函数
pid = kwait(int *status)
在kwait算法中,如果没有子进程,则进程会返回-1,表示错误。否则,他将搜索僵尸子进程。如果他找到僵尸子进程,就会收集僵尸子进程的pid和退出代码。相应的,当进程终止时,他必须发出:
kwakeup(running->parent)
唤醒父进程。
3.7Unix/Linux中的进程
操作系统启动时,内核会强行创建PID=0的初始进程,然后系统执行P0。系统挂载文件,然后初始化完成后,复刻出子进程P1。
P1运行时,执行映像更改为INIT程序,复刻出更多子进程,用于提供系统服务,这样的进程成为守护进程。
登录进程:登录后进程打开三个文件流,分别是stdin、stdout、stderr。
3.9 I/O重定向
sh进程有三个用于终端I/O的文件流:stdin(标准输入)、stdout(标准输出)、stderr(标准错误)。其文件描述符分别对应0、1、2。
在执行scanf("%s", &item);时,就会从stdin读入,如果其FILE结构体fbuf[]为空,它就会向Linux内核发出read系统调用,从终端/dev/ttyX或为终端/dev/pts/#上读入。
3.10 管道
管道是用于进程交换数据的单向进程间通信的通道。管道有一个输入端、一个输出端。在之前我们使用man -k | grep xx时,就用到管道的功能。
管道的使用可以通过程序完成,也可以在命令行中处理完成。
实践内容过程、问题解决过程
ps -ef|grep root
fork演示