一个模拟
n个就绪队列m个cpu的多级反馈调度算法
假设现在输入了num个进程,每个进程有到达时间和进程长度(执行需要的时间)
算法设计策略
- 沿用单个cpu的多级反馈调度算法
- 由于cpu有多个,缓存亲和性是一个重要问题,为了避免不同的cpu读写同一个进程带来的诸多麻烦,算法设计每个进程仅能被一个cpu调度
- 具体策略:在进程的PCB里用一个变量表示该进程只能被哪个cpu执行,一旦某个cpu开始调度该进程就做好标记,对于每个cpu,当其空闲的时候就按就绪队列的优先级顺序扫描队列,如果当前队列头部的进程PCB标识是该cpu,就为该进程分配时间片。
- 代码:(C语言实现)
-
1 #include <stdio.h> 2 3 typedef struct node{ 4 int needt; //还需要执行的时间 5 int cpun; //执行该进程的cpu 6 int num; 7 struct node* next; //队列里的下一个 8 }PCB; 9 typedef struct que{ 10 PCB* head;//该队列头部,为空说明队列空 11 PCB* tail; //队列尾部 12 int tblock; //时间块大小 13 struct que * next; //下一个队列 14 }Q; 15 16 int run = 0, n, m; //模拟时钟 n个队列,m个cpu 17 Q* HEAD; //队列表头 18 int cpu[20]={0}; //cpu剩下的执行时间 19 20 void buildqueue(){ //n个就绪队列的构建 21 Q* pre; 22 for(int i=0; i<n; i++){ 23 Q* tmp = (Q*)malloc(sizeof(Q)); 24 tmp -> next = 0; 25 tmp -> tblock = (1<<i); //分配时间片大小 26 tmp -> head = tmp->tail = 0; 27 if(i) { pre->next=tmp; pre = tmp; }else pre = HEAD = tmp; 28 } 29 } 30 31 void inserttail(PCB *ins, Q *tmp){ //吧ins插到tmp队尾 32 if(tmp->tail == NULL) { tmp->tail=tmp->head=ins; return; } 33 PCB *ti = tmp->tail; 34 ti->next = ins; 35 tmp->tail = ins; 36 } 37 38 void search(int x){ //为空闲的cpu分配程序 39 for(Q* it = HEAD; it!=NULL; it=it->next){ //从优先级高的队列开始分配 40 PCB* t = it->head; // 41 if(t != NULL){ //为cpu分配程序 42 if(t->cpun == 0) t->cpun=x; //没有被cpu执行的程序 43 if(t->cpun != x) continue; //只能被某个cpu执行 44 if(it->head == it->tail) it->head = it->tail = 0; 45 else it->head = t->next; //被执行,原来队首更新 46 if (it->tblock >= t->needt) { //分配时间片是否足够完成程序 47 cpu[x] = t->needt; 48 // printf("nowtime: %d,process%dis over\n", run+cpu[x], t->num); 49 free(t); //完成进程,释放进程的PCB 50 }else { 51 cpu[x] = it->tblock; //分配时间片 52 // printf("nowtime: %d,process%dis runningby\n", run, x); 53 t -> needt -= it->tblock; //程序需要时间减少 54 if(it->next!=NULL) inserttail(t, it->next); 55 else inserttail(t, it); //本来优先级就是最后的,直接时间片轮转 56 } 57 break; 58 } 59 } 60 } 61 62 void work(){ 63 run++; 64 printf("Now time:%d\n", run); 65 for(int i=1; i<=m; i++) { 66 if(cpu[i]) cpu[i]--; 67 if(!cpu[i]) search(i); //cpu空闲之后就为其分配程序 68 if(cpu[i]) printf("CPU[%d]=%d\n", i,cpu[i]); 69 else printf("CPU %d isfree\n", i); 70 } 71 } 72 73 int main(){ 74 scanf("%d%d", &n, &m); 75 buildqueue(); 76 int num, ari, ndtime; //进程的数量,到达时间,需要执行的时间 77 scanf("%d", &num); 78 for(int i=1; i<=num; i++) { 79 scanf("%d%d", &ari, &ndtime); 80 while(ari > run) work(); 81 PCB * np = (PCB *)malloc(sizeof(PCB)); 82 np -> next = 0; 83 np -> cpun = 0; 84 np -> needt = ndtime; 85 np -> num = i; 86 inserttail(np, HEAD); 87 } 88 int flag=1; 89 while(flag){ 90 flag = 0; 91 for(int i=1; i<=n; i++) if(cpu[i]) { flag=1; work(); } 92 } 93 return 0; 94 }
- 输入输出样例和解释:
- 输入(注意进程要按照到达时间从快到慢排序输入)
3 3 三个队列,三个cpu
3 三个进程
1 5
3 5
5 5
- 输出
Now time:1 现在是第一秒结束
CPU 1 isfree 三个cpu都是空闲
CPU 2 isfree
CPU 3 isfree
Now time:2 第二秒结束
CPU[1]=1 cpu1已经分配出去一个长度为1的时间片
CPU 2 isfree
CPU 3 isfree
Now time:3
CPU[1]=2 cpu1已经分配出去一个长度为2的时间片
CPU 2 isfree
CPU 3 isfree
Now time:4
CPU[1]=1
CPU[2]=1
CPU 3 isfree
Now time:5
CPU[1]=2
CPU[2]=2
CPU 3 isfree
Now time:6
CPU[1]=1
CPU[2]=1
CPU[3]=1
Now time:7
CPU 1 isfree
CPU[2]=2
CPU[3]=2
Now time:8
CPU 1 isfree
CPU[2]=1
CPU[3]=1
Now time:9
CPU 1 isfree
CPU 2 isfree
CPU[3]=2
Now time:10
CPU 1 isfree
CPU 2 isfree
CPU[3]=1
Now time:11
CPU 1 isfree
CPU 2 isfree
CPU 3 isfree 所有进程调度结束,所有cpu运行结束