新手小白
{
你不大可能看得懂,我也是写给自己看的。。。。
如果不想看,就直接拉到最后,有完整代码。
}
刚刚学习操作系统,还不能做实验,正好复习一下上学期的数据结构。
(发现单链表的有序插入排列都忘了,扣了半天。。还借鉴了别人的代码。)
模拟过程
1.按优先级高低对进程进行调度(可按优先级大小排好顺序),每个进程可有四个状态,即:“就绪”,“阻塞”,“执行”和“终止”(假设优先数越大优先级越高,以及进程的初始状态为就绪状态)。
2。为便于处理,应该随机地赋予所有进程各自的“优先级”和“要求运行的时间片数”,由用户给定。
3.程序中共有3个队列:就绪队列,阻塞队列和消亡(终止)队列。
4.进程每运行一次,优先级数减去1,要求的时间片数减1,如果要求的时间片数为零了,则将其加入消亡队列。否则,将其按照优先级的次序重新加入就绪队列。
5.进程运行过程中,遇到阻塞时,将该进程加入阻塞队列。(提示:可通过随机函数得到随机数,满足某种情况则使之加入到阻塞队列,或人为设置是否阻塞)
6.重复调度,直到就绪队列中所有进程全部运行结束。
首先就要有三个链表
优先级就绪态,阻塞态,终止态
- 单链表的有序插入(无头结点)借鉴这位前辈
Status Insert(PCB &L,PCB p){//将各个情况的结点自大到小插入
PCB pb=NULL,pf=NULL;
pf=L;
if(L==NULL){
L=p;
p->next=NULL;
}
while((p->prior<=pf->prior) && (pf->next!=NULL)){
pb=pf; //得到指针的前一个结点的指针
pf=pf->next;
}
if(p->prior>pf->prior){
if(pf==L){
L=p;
p->next=pf;
}
else{
pb->next=p;
p->next=pf;
}
}
else{
pf->next=p;
p->next=NULL;
}
return OK;
}
2.在建立玩链表的时候突然发现没有头结点,我记得老师说过要加上头结点便于操作,又要在最后加上。。。很烦
Status CreatReadyPcb(PCB &L_Ready){//就绪递减队列
InitList(L_Ready);
PCB p,p1,q;
p1=L_Ready;
int i,n;
printf("输入进程个数:\n");
scanf("%d",&n);
printf("输入进程信息:\n");
for(i=0;i<n;i++){
p=(PCB)malloc(sizeof(pcb));
printf("输入进程的内部标识(PID),时间片(time),优先级(prior):\n");
scanf("%d %d %d",&p->PID,&p->time,&p->prior);
strcpy(p->state,"ready");
Insert(L_Ready,p);
}
PCB pp;//加入空的头结点,之前忘加了...
InitList(pp);
pp->next=L_Ready;
L_Ready=pp;
printf("*****优先级就绪队列建立成功!*****\n");
return OK;
}
3.也就是最头疼的运行,有好几种状态(期间有时候要对链表加上或删除头节点)
我是输入数字代表阻塞的发生
- 不阻塞
时间片不为0:
优先级,时间片都减1
减一之后判断时间片是否为0
若为零,加入终止队列
不为零,则按优先级大小插入就绪链表
时间片为零
加入终止链表 - 阻塞
加入阻塞链表
void RunPcb(PCB &L_Ready,PCB &L_Block,PCB &L_Finish){
int n,count=0;
PCB p=L_Ready->next,p0,p2,pp,p4,pp1;
PCB p1=L_Finish;
PCB p5,ppp1;
printf("请输入阻塞数:\n");
scanf("%d",&n);
if(p->time!=n){//不阻塞
if(p->time!=0){//时间片不为0
p->time=(p->time)-1;
p->prior=(p->prior)-1;
if(p->time!=0){
fuZhi(p2,p);
DeleteList(L_Ready);
p4=L_Ready;//除去头结点
L_Ready=L_Ready->next;
free(p4);
strcpy(p2->state," ready ");
Insert(L_Ready,p2);//这个函数只能对没有头结点的链表操作
InitList(pp1);//加入空的头结点
pp1->next=L_Ready;
L_Ready=pp1;
//strcpy(L_Ready->next->state,"ready");
}
else{
fuZhi(p5,p);
DeleteList(L_Ready);
strcpy(p5->state," finish ");
Insert(L_Finish,p5);//这个函数只能对没有头结点的链表操作
}
}
else{//时间片为零
fuZhi(p2,p);
DeleteList(L_Ready);
strcpy(p2->state," finish ");
Insert(L_Finish,p2);
}
}
else{
fuZhi(p2,p);
DeleteList(L_Ready);
strcpy(p2->state," block ");
Insert(L_Block,p2);
}
}
最后就是一些小函数
1.头节点下一个节点的删除:
Status DeleteList(PCB &L){
int j=0;
PCB p,q;
p=L;
q=p->next;
p->next=q->next;
free(q);
return OK;
}
2.将一个节点属性复制给另一节点
void fuZhi(PCB &p1,PCB &p2){
InitList(p1);
p1=(PCB)malloc(sizeof(pcb));
p1->PID=p2->PID;
p1->time=p2->time;
p1->prior=p2->prior;
p1->next=NULL;
}
3.输出三个链表
void printPcb(PCB &L_Ready,PCB &L_Block,PCB &L_Finish){
PCB p1,p2,p3;
p1=L_Ready->next;
p2=L_Block;
p3=L_Finish;
printf("----------优先级就绪队列为:----------\n");
while(p1!=NULL && p1->prior!=-10){
printf("PID( %d )---state( %s )---need time( %d )---优先级(%d)\n",p1->PID,p1->state,p1->time,p1->prior);
p1=p1->next;
}
printf("----------阻塞队列为:----------\n");
while(p2!=NULL && p2->prior!=-10){
printf("PID( %d )---state( %s )---need time( %d )---优先级(%d)\n",p2->PID,p2->state,p2->time,p2->prior);
p2=p2->next;
}
printf("----------终止队列为:----------\n");
while(p3!=NULL && p3->prior!=-10){
printf("PID( %d )---state( %s )---need time( %d )---优先级(%d)\n",p3->PID,p3->state,p3->time,p3->prior);
p3=p3->next;
}
}
最后是完整c语言代码,有些操作重复了很多次,是可以用函数块代替的,可是我懒得写了。。。。
#include"stdio.h"
#include"stdlib.h"
#include"string.h"
#include"windows.h"
typedef int Status;
#define OK 1
typedef struct proc{
int PID;
char state[10];
int time;
int prior;
struct proc *next;
}*PCB,pcb;
Status InitList(PCB &L){
L=(PCB)malloc(sizeof(pcb));
L->PID=0;
L->time=0;
L->prior=-10;
L->next=NULL;
return OK;
}
Status Insert(PCB &L,PCB p){//将各个情况的结点自大到小插入
PCB pb=NULL,pf=NULL;
pf=L;
if(L==NULL){
L=p;
p->next=NULL;
}
while((p->prior<=pf->prior) && (pf->next!=NULL)){
pb=pf; //得到指针的前一个结点的指针
pf=pf->next;
}
if(p->prior>pf->prior){
if(pf==L){
L=p;
p->next=pf;
}
else{
pb->next=p;
p->next=pf;
}
}
else{
pf->next=p;
p->next=NULL;
}
return OK;
}
Status CreatReadyPcb(PCB &L_Ready){//就绪递减队列
InitList(L_Ready);
PCB p,p1,q;
p1=L_Ready;
int i,n;
printf("输入进程个数:\n");
scanf("%d",&n);
printf("输入进程信息:\n");
for(i=0;i<n;i++){
p=(PCB)malloc(sizeof(pcb));
printf("输入进程的内部标识(PID),时间片(time),优先级(prior):\n");
scanf("%d %d %d",&p->PID,&p->time,&p->prior);
strcpy(p->state,"ready");
Insert(L_Ready,p);
}
PCB pp;//加入空的头结点,之前忘加了...
InitList(pp);
pp->next=L_Ready;
L_Ready=pp;
printf("*****优先级就绪队列建立成功!*****\n");
return OK;
}
Status DeleteList(PCB &L){
int j=0;
PCB p,q;
p=L;
q=p->next;
p->next=q->next;
free(q);
return OK;
}
void fuZhi(PCB &p1,PCB &p2){
InitList(p1);
p1=(PCB)malloc(sizeof(pcb));
p1->PID=p2->PID;
p1->time=p2->time;
p1->prior=p2->prior;
p1->next=NULL;
}
void RunPcb(PCB &L_Ready,PCB &L_Block,PCB &L_Finish){
int n,count=0;
PCB p=L_Ready->next,p0,p2,pp,p4,pp1;
PCB p1=L_Finish;
PCB p5,ppp1;
printf("请输入阻塞数:\n");
scanf("%d",&n);
if(p->time!=n){//不阻塞
if(p->time!=0){//时间片不为0
p->time=(p->time)-1;
p->prior=(p->prior)-1;
if(p->time!=0){
fuZhi(p2,p);
DeleteList(L_Ready);
p4=L_Ready;//除去头结点
L_Ready=L_Ready->next;
free(p4);
strcpy(p2->state," ready ");
Insert(L_Ready,p2);//这个函数只能对没有头结点的链表操作
InitList(pp1);//加入空的头结点
pp1->next=L_Ready;
L_Ready=pp1;
//strcpy(L_Ready->next->state,"ready");
}
else{
fuZhi(p5,p);
DeleteList(L_Ready);
strcpy(p5->state," finish ");
Insert(L_Finish,p5);//这个函数只能对没有头结点的链表操作
}
}
else{//时间片为零
fuZhi(p2,p);
DeleteList(L_Ready);
strcpy(p2->state," finish ");
Insert(L_Finish,p2);
}
}
else{
fuZhi(p2,p);
DeleteList(L_Ready);
strcpy(p2->state," block ");
Insert(L_Block,p2);
}
}
void printPcb(PCB &L_Ready,PCB &L_Block,PCB &L_Finish){
PCB p1,p2,p3;
p1=L_Ready->next;
p2=L_Block;
p3=L_Finish;
printf("----------优先级就绪队列为:----------\n");
while(p1!=NULL && p1->prior!=-10){
printf("PID( %d )---state( %s )---need time( %d )---优先级(%d)\n",p1->PID,p1->state,p1->time,p1->prior);
p1=p1->next;
}
printf("----------阻塞队列为:----------\n");
while(p2!=NULL && p2->prior!=-10){
printf("PID( %d )---state( %s )---need time( %d )---优先级(%d)\n",p2->PID,p2->state,p2->time,p2->prior);
p2=p2->next;
}
printf("----------终止队列为:----------\n");
while(p3!=NULL && p3->prior!=-10){
printf("PID( %d )---state( %s )---need time( %d )---优先级(%d)\n",p3->PID,p3->state,p3->time,p3->prior);
p3=p3->next;
}
}
int main(){
PCB L_Ready,L_Block,L_Finish;
int n;
printf("******************************\n");
printf("1--->初始化\n");
printf("2--->创建就绪队列\n");
printf("3--->运行\n");
printf("4--->唤醒\n");
printf("5--->打印所有队列中的进程信息\n");
printf("0--->测试结束\n");
printf("******************************\n");
while(n!=0){
printf("请输入你的选择:\n");
scanf("%d",&n);
switch(n){
case 1:
InitList(L_Block);
InitList(L_Finish);
printf("初始化成功!\n");
break;
case 2:
CreatReadyPcb(L_Ready);
printPcb(L_Ready,L_Block,L_Finish);
break;
case 3:
RunPcb(L_Ready,L_Block,L_Finish);
printPcb(L_Ready,L_Block,L_Finish);
break;
case 4:
case 5:
printPcb(L_Ready,L_Block,L_Finish);
break;
}
}
return 0;
}