进程状态转换模拟
1、题目
针对进程五状态图,设计一个进程管理的模拟仿真系统。系统中,CPU有2个,输入设备1个,输出设备1个,进程上限为100个。
(1)设计每个进程的PCB结构(至少应该有进程号等信息),设计每个进程的代码指令集合(可以用输出语句模拟指令,这样程序的执行可以用输出结果来模拟),如某个程序的代码可以如下:
printf(”执行计算指令XXX; \n”);
printf(”执行输入指令III; \n”);
printf(”执行输出指令OOO; \n”);
(2)设计就绪队列、运行队列、阻塞队列;
(3)进程调度为时间片轮转调度,时间片自行设定大小(静态或者动态)。
(4)进程根据自身的指令集合中是否包含I/O指令分为纯计算型进程和I/O型进程,纯计算型进程时间片结束后,进入就绪转态,I/O型进程执行I/O指令会进入阻塞状态。
(5)输入设备和输出设备的管理采用先进先出调度。
(6)进程随机产生进入系统。
(7)其他自行设定的约束条件。
为了使参与并发执行的每个程序都能独立地运行,在操作系统中必须为之配置一个专门的数据结构,称为进程控制块(PCB)。系统利用PCB来描述进程的基本情况和活动过程,进而控制和管理进程。这样,由程序段、相关的数据段和PCB三部分构成了进程。
2、进程五种基本状态及转换
创建状态:如果进程所需的资源尚不能得到满足,比如系统尚无足够的内存使进程无法装入其中,此时,创建工作尚未完成,进程不能被调度运行,于是把此时进程所处的状态称为创建状态。
就绪状态:这里指进程已处于准备好运行的状态,即进程已分配到除CPU以外的所有必要资源后,只要在获得CPU,便可立即执行。
执行状态:这里指进程已获得CPU,其程序正在执行的状态。
阻塞状态:这里指正在执行的进程由于发生某事件暂时无法继续执行的状态,亦即进程的执行受到阻塞。
终止状态:当一个进程到达了自然结束点,或是出现了无法克服的错误,或是被操作系统所终结,或是被其他有终止权的进程所终结,它将进入终止状态。
图1:进程的五种基本状态及转换图
对于处于创建状态的进程,当其获得了所需的资源以及对其PCB的初始化工作完成后,即可由创建状态转入就绪状态。处于就绪状态的进程,在调度程序为之分配了处理机之后便可执行,相应地,其状态就由就绪状态转变为执行状态。正在执行的进程如果因分配给它的时间片已完而被剥夺处理机暂停执行时,其状态便由执行状态转为就绪状态。如果因发生某事件,致使当前进程的执行受阻,使之无法继续执行,即该进程状态将由执行状态转变为阻塞状态。当一个进程到达了自然结束点,或是出现了无法克服的错误,或是被操作系统所终结,或是被其他有终止权的进程所终结,它将进入终止状态。如图1所示。
3、设备
IDE:DEV-c++
操作系统:Windows
4、题目内容
(1)CPU有2个为别为:cpu_1、cpu_2;
进程数(进程上限):L 100;
时间片:T 10;
类型:type 1:计算,2:输入,3:输出;
进程号:pid;
运行时间:runtime;
进程:p;
进程控制块:PCB;
(2)就绪队列、阻塞队列:ready、wait;
线程(多线程):三个线程,分别为两个CPU,输入输出设备 pthread_t tids[3];
锁:pthread_mutex_t lock
由于有2个CPU,防止2个CPU同时访问一个进程,需锁住就绪队列,从就绪队列头部取出到执行,判断类型,如果是输入或者输出,则执行io请求,进入阻塞状态;若时间片大于0并且运行时间大于0,则进程执行计算指令XXX,若运行时间等于0,进程执行完成。否则,进程时间用完,时间片轮转调度。判断阻塞队列是否为空,从阻塞队列拿出(先进先出),进程执行输入指令III或执行输出指令OOO,最后结束。
5、代码及运行结果
5.1.代码:
#include <iostream>
#include <queue>
#include <time.h>
#include <stdlib.h>
#include <pthread.h>
#include <windows.h>
#define T 10 // 时间片
#define L 100 // 进程数
using namespace std;
struct PCB
{
int pid;
int runtime; // 运行时间
int type; // 类型 1:计算,2:输入,3:输出
};
queue<PCB*> ready, wait; // 就绪队列、阻塞队列
pthread_mutex_t lock; // 锁住就绪队列
void *cpu_1(void *)
{
int time_length = T;
PCB *pcb = NULL;
while(1)
{
if