操作系统作业2

请编写一个程序,模拟若干进程调度执行的情况。假设进程的状态分为执行和就绪两种。每个进程以其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<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
#include<cstring>
struct pcb{
    int pid;//进程id 
    int pstate; //进程状态 
    char pname[20];//映像名字
    int ptime;//剩余运行时间
    struct pcb *next; 
};
void addTofreeQueue(struct pcb *freeQueue,int i);//创建空白pcb 
void freeToready(struct pcb *freeQueue,struct pcb *readyQueue);//把创建好的空白pcb存入到ready对列中 
void readyTorun(struct pcb *readyQueue,struct pcb *runningQueue);//ready队列中的进程调度到run队列 
void running(struct pcb *p,struct pcb *runningQueue);//对ready队列传递过去的pcb进行操作,并输出结果 
void runningToready(struct pcb *m,struct pcb *readyQueue);//时间片到达将进程调度到readyQueue
void runningTofree(struct pcb *m,struct pcb *freeQueue);//时间片到达将进程调度到freeQueue
void ptf(struct pcb *readyQueue);//将readyQueue队列中的进程名称逐个输出 

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));
int main(){
    freeQueue->next=NULL;
    readyQueue->next=NULL; 
    runningQueue->next=NULL;
    printf("请输入进程数量 n:");
    int n,flag=1,t,j=1;
    char str[10];
    scanf("%d",&n);
    printf("每个进程运行使用的时间:\n");
    struct pcb *m,*p;
    for(int i=0;i<n;i++){ 
        p=freeQueue;
        while(p->next)
            p=p->next;
        m=(struct pcb*)malloc(sizeof(struct pcb));
        m->pid=i;
        m->pstate=0;
        sprintf(str,"%d",i);
        memset(m->pname,0,20);
        m->pname[0]='p';
        strcat(m->pname,str);
        scanf("%d",&m->ptime);
        p->next=m;
        m->next=NULL;
    }
    freeToready(freeQueue,readyQueue);
    while(flag){
        printf("第%d次运行\n",j);
        t=0;
        readyTorun(readyQueue,runningQueue); 
        p=readyQueue;
        while(p->next){
            t+=p->ptime;
            p=p->next;
        }
        if(t==0)
            flag=0;
        j++;
    }


    return 0; 
} 
void freeToready(struct pcb *freeQueue,struct pcb *readyQueue){
     //把freeQueue队列中的元素全部送入就绪队列中 ,这里可以直接readyQueue->next=freeQueue->next 
    struct pcb *f,*p; 
    p=freeQueue->next;
    f=readyQueue;
    while(p){

        freeQueue->next=p->next;
        while(f->next)
            f=f->next;
        f->next=p;
        p->next=NULL;
        p->pstate=1;
        p=freeQueue->next;
    }
}

void readyTorun(struct pcb *readyQueue,struct pcb *runningQueue){
//随机把一个在readyQueue队列中的pcb调度到running队列中 
    int random,length=0; 
    struct pcb *f,*p;
    f=readyQueue->next;

    while(f){//求readyQueue里面进程的数量 
        length++;
        f=f->next;
    }
    if(length==0){//判断readyQueue中是否还有进程存在 
        printf("进程运行完了");
    } 
    else{
        p=readyQueue; 
        srand(time(0));
        random=rand()%(length+1);//防止最后一个pcb不能运行 
        if(random==0)//防止pcb是readyQueue自己 ,readyQueue真是害人 
            random++; 
        for(int i=0;i<random;i++){//生成随机数 
            p=p->next;//随机生成指向一个在readyQueue队列中的一个元素 
        }
        f=readyQueue;
        while(f->next!=p)
            f=f->next;
        f->next=p->next;
        running(p,runningQueue); //把指到的pcb传入到running中 
    }
}
void running(struct pcb *p,struct pcb *runningQueue){//接受来自readyQueue队列的进程 
    struct pcb *m;
    if(runningQueue->next==NULL){
        runningQueue->next=p;
        p->next=NULL;
        p->pstate=2; 
        printf("第一个进程进入running队列,cpu开始工作\n"); 
        printf("%s(Ready->Running)\n",p->pname);
        printf("Running:%s\n",p->pname);
        p->ptime-=2;
        if(p->ptime>0){
            runningToready(p,readyQueue);
        }
        else{
            runningTofree(p,freeQueue);
        }
    }
    else{
        m=runningQueue->next;
        m->ptime-=2;
        if(m->ptime>0){
            runningToready(m,readyQueue);
        }
        else{
            runningTofree(m,freeQueue);
        }
        runningQueue->next=p;
        p->pstate=2;
        p->next=NULL;
        printf("Sched: %s(Running -> Ready),%s(Ready->Running)\n",m->pname,p->pname);
        printf("Running:%s\n",p->pname);
    }
    ptf(readyQueue);
}

void runningToready(struct pcb *m,struct pcb *readyQueue){
    //将没完成的进程调回到readyQueue队列
    printf("进入runningToready\n");

    struct pcb *p;
    p=readyQueue;
    while(p->next){
        p=p->next;

    }
    p->next=m;
    m->next=NULL;
    m->pstate=1;
}
void runningTofree(struct pcb *m,struct pcb *freeQueue){
    //把不需要运行时间的进程放到freeQueue
    struct pcb *p;
    p=freeQueue;
    while(p->next){
        p=p->next;
    }
    m->next=p->next;
    m->next=NULL;
}
void ptf(struct pcb *readyQueue){
    struct pcb *p;
    int flag=1;
    p=readyQueue->next;
    while(p){
        if(flag==1){
            printf("%s",p->pname);
            flag=0;
        }
        else{
            printf("->%s",p->pname);
        }
        p=p->next;
    }
    printf("\n");
}
?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值