进程
描述和管理程序的“运行过程”-------进程
进程概念
定义:进程是程序在某个数据集合上的一次运行活动
进程的特征
-
动态性
进程是程序的一次执行过程,动态产生消亡
-
并发性
进程可以同其他程序一起向前推进
-
异步性
进程按各自的速度向前推进
-
独立性
进程是系统分配资源和调度CPU的单位
进程的状态
-
运行状态
进程已经占有CPU,在CPU上运行 -
就绪状态
具备运行条件但由于无CPU,暂时不能运行 -
阻塞状态
应为等待某项服务完成或信号来到而不能运行的状态
例如等待:系统调用,I/O操作,合作进程的服务或信号
进程状态的变迁
进程的挂起和解挂操作
挂起:用户或OS将进程有意暂停
解挂:将挂起的进程继续
阻塞:禁止阻塞(阻塞时挂起)和活动阻塞(正常阻塞)
就绪:禁止就绪(就绪时挂起)和活动就绪(正常就绪)
Linux进程状态
- 可运行态:TASK_RUNNING
1.就绪:在就绪队列中等待调度
2.运行:正在运行 - 阻塞(等待)态:
1.浅度阻塞:TASK_INTERRUPTIBLE
可被其他进程的信号或时钟中断唤醒
2.深度阻塞:TASK_UNINTERRUPTIBLE
不可被其他进程通过信号或时钟中断唤醒 - 僵死态:TASK_ZOMBIE
进程终止执行,释放大部分内存 - 挂起态:TASK_STOPPED
进程被挂起
进程的描述
进程控制块(PCB)
1.描述进程状态、资源、和相关进程关系的一中数据结构
2.PCB是进程的标志
3.创建进程时创建PCB;进程撤销后PCB同时撤销
进程=程序+PCB
Linux的进程控制块PCB:task_struct
Linux 进程的标识:
PID
PPID:父进程ID
PGID:进程组ID
Linux进程的用户标识:
UID:用户ID
GID:用户组ID
STAT:进程状态
符号 | 含义 |
---|---|
R | 运行或准备运行 |
S | 睡眠状态 |
I | 空闲 |
Z | 僵尸 |
D | 不间断睡眠 |
W | 进程没有驻留页 |
T | 停止或跟踪 |
进程控制
四个典型控制为:
- 创建进程
- 撤销进程
- 阻塞进程
- 唤醒进程
创建进程的过程
创建一个空白PCB
赋予进程标识符ID
为进程分配空间
初始化PCB(默认值)
插入相应的进程队列(新进程插入就绪队列)
进程撤销过程
在PCB队列中检索出PCB
获取该进程状态
- 若在运行态,立即终止该进程
- 递归检查是否有子进程,先撤销子进程
释放进程占有的资源
将进程从PCB队列中移除
- 递归检查是否有子进程,先撤销子进程
进程阻塞时机和过程
时机;
- 请求系统服务
- 启动某种操作
- 新数据尚未到达
- 无新工作可做
停止运行
将PCB“运行态”改为“阻塞态”
插入相应原因的阻塞队列
转调度程序
进程唤醒
系统服务由不满足到满足
I/O完成
新数据到达
进程提出新请求
进程控制原语:
- 创建原语
- 撤销原语
- 阻塞原语
- 唤醒原语
Linux进程控制
创建进程fork
fork执行流程:
- 分配task_struct结构
- 为新进程堆栈分配物理页
- 拷贝父进程内容
- 正文段、用户数据段及系统数据段task_struct的大部分内容,并对子程序中有别于父进程的项进行初始化
- 把新进程的task_struct结构地址保存在task指针数组中
- 子进程由fork创建后,通常属于就绪状态
init进程:
在linux系统初启时,生成init进程(1号进程)
其他进程有当前进程通过系统调用fork建立
子进程执行自己的功能
exce函数族
功能:
- 装入一个指定的可执行程序运行
- 使子进程具有和父进程完全不同的新功能
步骤:
- 根据文件名找到相应的可执行文件
- 可执行文件的内容填入子程序的地址空间
- exce调用成功就会进入新进程且不再返回
- 调用失败返回-1,继续在克隆来的地址空间中从调用点向下执行
进程阻塞 wait
进程立即阻塞自己,如果它找到一个已经成为僵尸的子进程,wait就会收集这个子进程的信息,并把它彻底销毁后返回
进程终结exit
进程释放自己占用的资源并汇报给父进程
调用exit后变为僵尸态,几乎所有的内存空间,保存PCB信息供wait收集
进程的休眠sleep
Windows进程
进程是被加载到内存的,正在运行的应用程序实例
进程由内核对象和地址空间所组成
- 内核对象PCB
- 地址空间
包括代码、数据、堆、栈、堆上动态分配的空间
windows创建进程creatProcess
过程:
- 创建进程内核对象,创建虚拟地址空间
- 装载exe和、或dll的代码和数据到地址空间中
- 创建主线程和线程内核对象
- 启动主线程,进入主函数
有一个非常有趣的例子,见我另一篇博客
Windows结束进程
主函数返回
ExitProcess
TerminateProcess
补充:守护进程daemon
守护进程编程:
pid = fork(); //创建子进程
if(pid>0)
eixt(0); //退出父进程
setsid(); //让进程脱离控制终端
chdir("/"); //避免原工作目录不能被卸载
umake(0); //文件权限掩码设置0
for(int i = 0;i<MAXFILE;i++)
close(i); //关闭继承自父进程的文件