一、基本概念
1.1 程序和进程
-
A program is a passive entiy,such as a file containing a list of instructions stored on disk(ofen called an executable file)
程序是一个存在磁盘上包含一系列指令的被动实体,程序只能被动加载到内存而不是主动加载
-
A program becomes a process when an executable file is loaded into memory
当程序的可执行文件加载进内存就变成了程序进程
-
A process is an active entity,with a program counter specifying the next instruction to execute an a set of associated resource
进程是一个活跃的实体,包含了一个指明下一条指令将要执行哪些相关资源的程序计数器(PC),每个进程都有一个程序计数器
1.2 程序计数器(program counter)
- 程序计数器(PC)通常是一个CPU中的寄存器,里面存放下一条要执行指令的内存地址,在X86和Itanium微处理器中,它叫做指令指针(Instruction Point,IP),有时又被称为指令寄存地址(instruction address register,IAR)、指令计数器
- 通常,CPU在取完一条指令之后会将PC寄存器的值加”1“,以计算下条要执行指令的地址。
1.3 Process In Memory
- text:用于存放编译后的二进制代码
- data:用于存放全局和静态(static修饰)变量
- stack:栈用于存放局部变量、函数返回地址
- heap:堆用于程序运行时的动态内存分配(malloc)
1.4 并发进程
-
Concurrency:the fact of two or more events or circumstances happening or existing at the same time
在同一时间,多个事件同时发生或存在
-
与”并行“的区别
并行:同一时间,多个事件同时运行(Running)(多个CPU)
并发:同一事件,多个事件同时发生或存在,但只能有一个可以运行(单个CPU)
-
进程并发的动机:多道程序设计
1.5 并发进程共享CPU
- 并发进程可能无法一次性执行完毕,会走走停停
- 一个进程在执行过程中可能被另一个进程替换占有CPU,这个过程称作”进程切换”
1.6 进程的定义
- 进程是一个程序的一次执行过程(一个程序可以启动多个进程,比如QQ)
- 能完成具体的功能
- 在某个数据集合上完成
- 执行过程是可并发的
- 进程是资源分配、保护和调度的基本单位
二、详解进程
2.1 进程状态
进程在执行期间自身的状态会发生变化,进程有三种基本状态,分别是:
- 运行态(Running):此时进程的代码在CPU上运行
- 就绪态(Ready):进程具备运行条件,但因为此时其他进程在CPU上运行而暂停运行,等待分配CPU时间片
- 等待态(Waiting):进程等待某些事件的发生(比如IO操作结束或是一个信号)
进程除了在执行期间的这三种状态,还有初始化状态和终止状态
状态变迁图:
- 新创建的进程刚开始处于初始化状态
- 然后进程进入就绪状态,等待CPU时间片到达
- CPU时间片达到后,进程处于运行状态
- 当发生中断时,进程又进入就绪状态;或者需要I/O等待事件时,进入阻塞状态(等待状态)
- 当I/O等待事件完成时,又处于就绪状态,重复上面步骤
- 当进程运行完成之后退出,变成终止状态
2.2 进程何时离开CPU
-
内部事件
进程主动放弃(yield)CPU,进入等待/终止状态
使用I/O设备,(非)正常结束
-
外部事件
进程被剥夺CPU使用权,进入就绪状态。这个动作叫抢占(preempt)
时间片到达,高优先级进程到达(分时系统)
2.3 中断
中断是指程序执行过程中
-
当某个事件发生时,中止CPU上现行程序的运行
-
引出该事件的处理程序执行(内核中运行)
-
执行完毕后返回原程序中断点继续执行
中断根据中断源又分为程序内部异常和外部事件中断
外中断:来自处理器之外的硬件中断信号
- 如时钟中断、键盘中断、外围设备中断
- 外部中断均是异步中断(随机)
内中断(Exception): 来自处理器内部,指令执行过程中发生的中断,属同步中断
- 硬件异常:掉电、奇偶检验错误等
- 程序异常:非法操作、地址越界、断点、除数为0
- 系统调用
2.4 中断处理过程
- 当执行程序遇到内部异常或外部事件发生中断时,首先需要将该程序在内存中的所有数据保存至上下文信息(context)中
- 陷入内核,根据不同的中断源选择不同的处理程序,由内核完成中断程序
- 选择一个进程恢复并重新开始,恢复选择进程的上下文信息,然后恢复执行已选择的程序
2.5 特权指令和非特权指令
-
Privileged Instructions(特权指令)
只能在内核模式中运行的指令称为特权指令
- I/O指令和停止指令
- 关闭所有的中断
- 设置定时器(Timer)
- 进程切换
-
Non-Privileged Instructions(非特权指令)
只能在用户模式下运行的指令称为非特权指令
-
模式切换
- 中断是用户态向核心态转换的唯一途径!系统调用实质上也是一种中断。
- OS提供Load PSW装载用户进程返回用户状态
2.6 进程切换
切换时机
- 进程需要进入等待状态(主动)
- 进程被抢占CPU而进入就绪状态(被动)
切换进程
user mode -> kernel mode ->user mode
- 保存被中断进程的上下文信息(Context)
- 修改被中断进程的控制信息(如状态等)
- 将被中断的进程加入相应的状态队列
- 调度一个新的进程并恢复它的上下文信息
2.7 进程控制块
为了实现进程模型,操作系统维护着一张表格(一个结构数组),即进程表,也称之为进程控制块(Process Control Block,PCB),每个进程都有一个与之对应的PCB,该PCB包含了进程状态的重要信息,包括程序计数器、堆栈指针、内存分配情况、所打开的文件状态,以及其他在进程由运行态转换到就绪态或阻塞态时必须保存的信息,从而保证该进程随后能再次进入运行态运行,就像从未被中断过一样。
PCB包含的是进程的所有控制信息,加上前文所说的text、data、heap、stack数据就构成了进程在内存中的所有数据,即上下文信息(Context)
2.8 进程调度
进程在整个生命周期中,会在各个调度队列中迁移,由操作系统的一个调度器(scheduler)来执行
三、子进程
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{
printf("Before fork processid:%d\n", getpid());
fork();
printf("After fork processid:%d\n",getpid());
pause();
return 0;
}
fork()函数用于创建一个子进程,子进程拥有和父进程完全一样的内存数据,只是进程号以及父进程号不同,利用fork创建子进程之后,fork()函数后面的代码会执行两遍,父子进程各执行一遍,因为父子进程的程序计数器是一样的。
父子进程拥有相互独立的内存空间,两个进程并发执行
子进程的优势:得到了两个并发执行的执行流
子进程的劣势:内存数据一摸一样,浪费内存空间
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/153687.html