操作系统作业02
2019-07-14 10:44发布
生成海报
操作系统作业02
题目
请编写一个程序,模拟若干进程调度执行的情况。假设进程的状态分为执行和就绪两种。每个进程以其PCB为代表即可,无需创建真正的进程。
以链表的方式组织PCB,分为三个队列: freeQueue:一个空白PCB队列 readyQueue:一个就绪队列
runningQueue:一个执行队列
程序开始运行时,用户输入进程数量n,以及每个进程需要运行的时间t0/t1/…/tn。程序从空白PCB队列中取出PCB创建进程,插入readyQueue。
进程的调度采用随机的方式,即从就绪队列中随机选择一个进程投入运行(就是将该PCB中的状态变量赋值为“运行”)。相应的修改其所在队列,并且原来处于运行态的进程需要转变为“就绪”态,插入readyQueue。
假设时间片是2,进程每次调度运行后,其还需运行的时间应该减少2,直至为0,即表示该进程执行完毕。需要回收PCB到freeQueue。
每次发生调度的时候,需要打印信息示例: Sched: P0(Running -> Ready), P3(Ready -> Running)
Running: P3 Ready: P1->P2->P0
上述信息表示调度时P0处于运行态,选择P3运行,P0进程的PCB进入就绪队列,并且在队尾。就绪队列是按照队列节点次序输出进程名称。
示例片段代码:
#define free 0
#define ready 1
#define running 2
#define ts 2 /* time slice */ struct PCB {
int pid; /* 进程ID */
int pstate; /* 进程状态 */
char pname; / 映象名称 */
int ptime; /* 剩余运行时间 */
struct PCB pnext; / 下一个PCB */ }
代码实现
#include
#include
#include
#include
#include
#define free 0
#define ready 1
#define running 2
#define ts 2 /* time slice */
struct PCB {
int pid;
int pstate;
char pname[20];
int ptime;
struct PCB *pnext;
};
int PCBchange(int isEmpty[],int run,int PCB_num){
int lrun = rand()%PCB_num;
while(run==lrun || isEmpty[lrun]<0){
lrun = rand()%PCB_num;
}
return lrun;
}
struct PCB * findAndSwitch(int Id,struct PCB * tp,struct PCB * sp){
struct PCB * getP;
struct PCB * temp;
getP = tp;
while(getP->pnext!=NULL&&getP->pnext->pid != Id){
getP = getP->pnext;
}
temp = getP->pnext;
if(temp->pnext!=NULL){
getP->pnext = temp->pnext;
}else{
getP->pnext = NULL;
}
getP = sp->pnext;
sp->pnext = temp;
temp->pnext = NULL;
return getP;
}
void outputReady(struct PCB* tp){
struct PCB* getP;
printf("Ready:");
if(tp->pnext!= NULL){
getP = tp->pnext;
printf("%s",getP->pname);
getP = getP->pnext;
while(getP!=NULL){
printf("->%s",getP->pname);
getP = getP->pnext;
}
printf("
");
}else
printf("NULL
");
}
int main()
{
struct PCB * freeQueue = (struct PCB*)malloc(sizeof(struct PCB));
struct PCB * readyQueue = (struct PCB*)malloc(sizeof(struct PCB));
struct PCB * runningQueue = (struct PCB*)malloc(sizeof(struct PCB));
struct PCB * temp;
struct PCB * getP;
int PCB_num;
char str[10];
int isEmpty[50]={0};
int i=0;
int run=-1;
int counter = 0;
int isComplete=1;
srand((unsigned) time(NULL));
runningQueue->pnext = NULL;
printf("请输入进程数量:");
scanf("%d",&PCB_num);
printf("请依次输入每个进程运行耗时:");
getP = freeQueue;
for(i;istruct PCB*)malloc(sizeof(struct PCB));
temp->pid = i;
temp->pstate = 0;
sprintf(str, "%d" , i);
memset(temp->pname, 0, 20);
temp->pname[0] = 'P';
strcat(temp->pname, str);
scanf("%d",&(temp->ptime));
temp->pnext = NULL;
getP->pnext = temp;
getP = getP->pnext;
isEmpty[i] = i;
}
readyQueue->pnext = freeQueue->pnext;
freeQueue->pnext = NULL;
while(isComplete){
run = PCBchange(isEmpty, run, PCB_num);
if(runningQueue->pnext==NULL){
getP = findAndSwitch(run,readyQueue,runningQueue);
printf("Sched:%s(Ready->Running)
",runningQueue->pnext->pname);
printf("Running:%s
",runningQueue->pnext->pname);
outputReady(readyQueue);
}
else{
getP = findAndSwitch(run, readyQueue, runningQueue);
temp = readyQueue;
while(temp->pnext!=NULL)
temp = temp->pnext;
temp->pnext = getP;
printf("Sche:%s(Running->Ready),%s(ready->Running)
",
getP->pname,runningQueue->pnext->pname);
printf("Running:%s
", runningQueue->pnext->pname);
outputReady(readyQueue);
}
runningQueue->pnext->ptime -= 2;
for(i=0;iif(isEmpty[i] == -1)
{
isEmpty[i] = -2;
temp = readyQueue;
while(temp->pnext->pid != i)
temp = temp->pnext;
if(temp->pnext!=NULL){
getP = temp->pnext;
temp->pnext = getP->pnext;
}else{
getP = temp->pnext;
temp->pnext = NULL;
}
getP->pnext = freeQueue->pnext;
freeQueue ->pnext = getP;
printf("Sche:%s(Ready->free)
",getP->pname);
counter ;
}
}
if(runningQueue->pnext->ptime<=0){
isEmpty[run] = -1;
}
if(counter == PCB_num-1){
printf("Sche:%s(Ready->free)
",runningQueue->pnext->pname);
isComplete = 0;
}
}
return 0;
}
运行结果
小结
本次作业,发现了很多不足,比如在链表操作时经常遇到空指针问题,代表自己的指针操作还是不甚熟料,同时,犯了上手就写代码的错误,导致后期很多链表操作的代码重复,以至于后期不易调试导致我几乎重写把链表全都封到函数中,不过就算现在的代码逻辑也不是很清晰,下次一定要先构思再下手
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮