实验目的
能够模拟操作系统内核对进程的控制和管理:包括进程的创建和撤销、进程状态的切换和简单的内存空间管理。
实验内容
- 能够模拟进程的创建和撤销过程
- 对进程的状态进行全面的控制
- 按先进先出的方式管理就绪和阻塞队列,按队列输出进程状态
- 完成可变分区的分配和回收
- 界面清晰友好
- 实验结束后撰写实验报告
数据结构
两条链表,构成两个对列,running_list和blocked_list队列;
running_list存放当前正在运行的线程,默认头结点是正在运行的线程,其余后继结点是就绪状态的进程;
blocked_list存放当先处于阻塞状态中的线程;
算法设计
创建:判断内存是否已满,判断是否重名,均满足条件后,输入该进程其他信息,并将其加入就绪队列
展示:展示运行进程和就绪进程
阻塞:判断是否是就绪队列中的运行进程,满足条件,将该运行进程插入到阻塞队列中
唤醒:判断该进程是否在阻塞队列中,满足条件,将其插入到就绪队列中,等待运行
终止:判断该进程是否在运行进程中,满足条件,找到并释放
实验流程图
实验代码
#include<iostream>
#include<malloc.h>
#include<assert.h>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
//进程状态
enum Process_State
{
Pro_State_blocked = 1,
Pro_State_running = 2,
};
//PCB结构体
typedef struct PCB{
int id;
int size;
char content[20];
int state;
struct PCB *next;
}PCB;
PCB *running_list = (PCB *)malloc(sizeof(PCB));
PCB *blocked_list = (PCB *)malloc(sizeof(PCB));
void create(PCB *running_list, PCB *blocked_list, int *size);
void show(PCB *running_list);
void change(PCB *running_list, PCB *blocked_list, int *size);
void kill(PCB *running_list, int *size);
void awake(PCB *running_list, int *blocked_list, int *size);
int isExist_running(PCB *running_list, int id);
int isExist_blocked(PCB *running_list, int id);
PCB *find(PCB *list, int id);
void create(PCB *running_list, PCB *blocked_list, int *size)
{
//无效判断 测试用例大小为10000时 无法实现 留待改进
PCB *pro = (PCB *)malloc(sizeof(PCB));
assert(pro != NULL);
int id;
cout<<"请输入进程名,判断是否重复"<<endl;
cin >> id;
//cout<<"1111"<<endl;
//判断进程是否重名,分两种,在运行和阻塞
//为什么出错?
//发现错误 main函数中阻塞队列出错
if(isExist_running(running_list,id)){
cout << "进程重名了,换个名字继续吧" << endl;
return;
}
if(isExist_blocked(blocked_list,id)){
cout << "进程重名啦,换个名字继续吧" << endl;
return;
}
//没重名
pro->id=id;
//输入PCB的其他属性值
cout<<"请输入进程的大小"<<endl;
cin>>pro->size;
if (pro->size >= 1024)
{
cout << "内存不足,换个小一点的程序吧" << endl;
return;
}
cout<<"请输入进程的内容"<<endl;
cin>>pro->content;
pro->state=Pro_State_running;
pro->next=NULL;
PCB *npro=running_list;
while(npro->next!=NULL){
npro = npro->next;
}
npro->next= pro;
*size=*size+1;
}
void show(PCB *running_list)
{
PCB *npro = running_list->next;
if (npro == NULL)
{
cout << "该时刻没有正在运行的进程" << endl;
return;
}
while (npro != NULL)
{
cout << "进程名:" << npro->id << endl;
cout << "进程大小:" << npro->size << endl;
cout << "进程内容:" << npro->content << endl;
npro = npro->next;
}
}
void change(PCB *running_list, PCB *blocked_list, int *size)
{
if (*size == 0)
{
cout << "没有可以阻塞的进程" << endl;
return;
}
int id;
cout << "请输入需要阻塞的进程名字:";
cin >> id;
//判断进程是不是在就绪队列中
if (isExist_running(running_list, id))
{
//在,找到位置
PCB *npro = find(running_list, id);
//修改这个进程的状态
npro->next->state = Pro_State_blocked;
//放在就绪队列,findposition insert move
PCB *pro = blocked_list;
while (pro->next != NULL)
{
pro = pro->next;
}
pro->next = npro->next;
npro->next = npro->next->next;
pro->next->next = NULL;
*size = *size - 1;
cout << "已经将进程换出到阻塞队列" << endl;
}
else
cout << "改进程不存在或者已经在就绪队列中" << endl;
}
void kill(PCB *running_list, int *size)
{
if (*size == 0)
{
cout << "没有可以杀死的进程" << endl;
return;
}
int id;
cout << "请输入要杀死的进程:" << endl;
cin >> id;
//判断是否存在 find reserve move delete
if (isExist_running(running_list, id))
{
PCB *npro = find(running_list, id);
PCB *location = npro->next;
npro->next = npro->next->next;
*size = *size - 1;
free(location);
cout << "已经杀死该进程" << endl;
}
else
cout << "该进程不存在,或者已处于阻塞队列中" << endl;
}
void awake(PCB *running_list, PCB *blocked_list, int *size)
{
PCB *npro = blocked_list;
if (npro->next == NULL)
{
cout << "没有可以唤醒的进程" << endl;
return;
}
int id;
cout << "请输入要唤醒的进程名字:" << endl;
cin >> id;
//判断是否存在 find return change insert
if (isExist_blocked(blocked_list, id))
{
npro = find(blocked_list, id);
npro->next->state = Pro_State_running;
PCB *pro = running_list;
while (pro->next != NULL)
{
pro = pro->next;
}
pro->next = npro->next;
npro->next = npro->next->next;
pro->next->next = NULL;
*size = *size + 1;
cout << "已成功唤醒进程" << endl;
}
else
cout <<"改进程不存在" << endl;
}
int isExist_running(PCB *running_list, int id)
{
int result = 0;
PCB *pro = running_list->next;
while (pro != NULL)
{
if (pro->id == id)
{
result = 1;
break;
}
pro = pro->next;
}
return result;
}
int isExist_blocked(PCB *blocked_list, int id)
{
int result = 0;
PCB *pro = blocked_list->next;
while (pro != NULL)
{
if (pro->id=id)
{
result = 1;
break;
}
pro = pro->next;
}
return result;
}
PCB *find(PCB *list, int id)
{
PCB *pro = list;
while (pro->next != NULL)
{
if (pro->next->id == id)
{
return pro;
}
pro=pro->next;
}
return NULL;
}
int main()
{
//就绪队列
running_list->next = NULL;
//阻塞队列
//找到错误点 =-
blocked_list->next = NULL;
int pro_size = 0;
char choose;
while (1)
{
cout << "欢迎来到我的进程控制系统" << endl;
cout << "请输入序号以选择如下功能" << endl;
cout << "1-创建新进程" << endl;
cout << "2-展示当前进程" << endl;
cout << "3-阻塞执行进程" << endl;
cout << "4-唤醒阻塞进程" << endl;
cout << "5-终止执行程序" << endl;
cout << "6-退出程序" << endl;
cin>>choose;
switch (choose)
{
case '1':
create(running_list, blocked_list, &pro_size);
break;
case '2':
show(running_list);
break;
case '3':
change(running_list, blocked_list, &pro_size);
break;
case '4':
awake(running_list, blocked_list,&pro_size);
break;
case '5':
kill(running_list, &pro_size);
break;
case '6':
return 0;
default:
cout << "出错啦,请输入序号" << endl;
break;
}
}
return 0;
}
运行示例
实验小结
实验缺陷:判断内存容量和正在运行的线程总大小,存在缺陷,留待完善。//已改进
实验改进:判断内存容量,但没有输入第一个进程的大小,只给它初始化为0,所以会出现问题,判断语句要在进程大小输入后再判断,实验缺陷已改进。
实验心得:耐心,细心,遇到errors不要慌,一个一个改,总能改完。