Linux编程:模拟进程调度算法
来源:互联网 发布:服装销售数据怎么分析 编辑:程序博客网 时间:2024/06/07 20:32
稍稍有点操作系统基础的朋友应该知道进程的调度算法,在这里Koala还是给大家略微介绍一下接下来将要用到的几种算法:
- 先来先服务(FCFS)
采用FCFS调度,先请求CPU的进程会先分配到CPU。
使用FCFS调度的等待时间通常较长,CPU利用率也会较低 - 最短作业优先调度(SJF)
采用SJF调度会选择具有最短CPU运行时间的进程分配CPU使用权。如果两个进程的CPU区间相同,则按照FCFS来进行选择。
SJF调度可以证明是最佳的,它降低了平均等待时间。 - 轮转法调度(RR)
RR调度将CPU时间分为较小的时间片,调度程序循环就绪队列。为每一个进程分配不超过一个时间片的CPU。
RR调度专门用于分时系统。 - 优先级调度
每一个进程都有一个优先级与其关联,具有最高优先级的进程会分配到CPU。
优先级调度的一个主要问题是优先级较低的进程会产生饥饿现象。
整个编程思路按照如下进行:
创建主线程,主线程创建子线程,子线程有一个虚拟PCB
主线程创建20个子线程,分别实现FCFS调度、SJF调度、RR调度、优先级调度,并且计算每个调度的平均等待时间。
对于每个子线程,在其运行期间,输出其占用的时间标号(例如,第3个线程占用了第10秒的CPU时间,输出为:“Thread3:10”)。
下面是整个的代码(仅供参考):
#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<unistd.h>#include<pthread.h>#include<time.h>#include<iostream> #define Thread_Num 20using namespace std;pthread_mutex_t Device_mutex ;//Virtual PCB of threads struct VirtualPCB{ int tid; int priority; int waittime; int runtime; int arrivetime; int visited; int tempruntime; public: int gettid() { return tid; } int getwaittime() { return waittime; } int getpriority() { return priority; } int getruntime() { return runtime; } int getarrivetime() { return arrivetime; } void setvisit(int a) { visited=a; } int getvisit() { return visited; } int gettempruntime() { return tempruntime; } void setwaittime(int n) { waittime = n; } void settempruntime(int n) { tempruntime = tempruntime - n; }}TCB[Thread_Num]; //Function to initial virtual PCBvoid t_init(){ int n; srand(time(NULL)); for(n =0;n<Thread_Num;n++) { TCB[n].tid = n + 1;//用线程创建序号作为虚拟进程id //用随机数随机产生虚拟PCB的值 TCB[n].priority = 1 + rand()%19; TCB[n].runtime = 1 + rand()%19; TCB[n].arrivetime = 0;//模拟时,默认进程按创建顺序依次在0时刻到达 TCB[n].waittime = 0; TCB[n].visited =0; TCB[n].tempruntime = TCB[n].runtime; }}//Threads run functionvoid *t_print(void *arg){ int n = *(int *)arg;//get argument while(1) { pthread_mutex_lock(&Device_mutex); printf("Thread_%-2d: ",n); printf("tid:%-2d priority:%-2d runtime:%-2d \n",TCB[n-1].gettid(),TCB[n-1].priority,TCB[n-1].runtime); pthread_mutex_unlock(&Device_mutex); sleep(1); break; } //printf("Error %d\n",n); pthread_exit(0);}//First come first service schedule functionvoid FCFS(){ cout<<"-----------FCFS:"<<endl; int i,j; int start = 0; float waittime = 0; float avwait = 0; for(i=0;i<Thread_Num/2;i++) { for(j=0;j<Thread_Num;j++){ if(TCB[j].getarrivetime()==i && TCB[j].getvisit()==0){ printf("Thread: %-2d Start: %-3d Runtime: %-2d\n",TCB[j].gettid(),start,TCB[j].getruntime()); waittime = waittime + (float)start; start = start + TCB[j].getruntime(); TCB[j].setvisit(1); } } } avwait = waittime / (float)Thread_Num; printf("Total waitting time : %f\n",waittime); printf("Average waitting time : %f\n",avwait);}//Shortest job first schedule functionvoid SJF(){ for(int k=0 ;k<Thread_Num;k++) { TCB[k].setvisit(0); } cout<<"-------------SJF:"<<endl; int i,j; int start = 0; float waittime = 0; float avwait = 0; for(i=1;i<Thread_Num;i++) { for(j=0;j<Thread_Num;j++){ if(TCB[j].getruntime()==i && TCB[j].getvisit()==0){ printf("Thread: %-2d Start: %-3d Runtime: %-2d\n",TCB[j].gettid(),start,TCB[j].getruntime()); waittime = waittime + (float)start; start = start + TCB[j].getruntime(); TCB[j].setvisit(1); } } } avwait = waittime / (float)Thread_Num; printf("Total waitting time : %f\n",waittime); printf("Average waitting time : %f\n",avwait);}//Round R schedule functionvoid RR(int r){ cout<<"--------------RR:"<<endl; int start = 0; float waittime = 0; float avwait = 0; for(int i=0;i<Thread_Num;i++) { int totaltime = totaltime + TCB[i].getruntime(); TCB[i].setvisit(0); } for(int j=0;j<20*Thread_Num;j=j+r) { int k = (j%(20*r))/r; if(TCB[k].gettempruntime() > 0){ int tepruntime = r; if(TCB[k].gettempruntime()-r<=0){ tepruntime = TCB[k].gettempruntime(); TCB[k].setwaittime(start + tepruntime - TCB[k].getruntime()); } printf("Thread: %-2d Start: %-3d Runtime:%-2d \n",TCB[k].gettid(), start,tepruntime); start = start + tepruntime; TCB[k].settempruntime(r) ; } } for(int m=0;m<Thread_Num;m++) { waittime += TCB[m].getwaittime(); //printf("TCB[%d].getwaittime():%d\n",m+1,TCB[m].getwaittime()); } avwait = waittime / (float)Thread_Num; printf("Total waitting time : %f\n",waittime); printf("Average waitting time : %f\n",avwait);}//Priority schedule functionvoid Priority(){ for(int k=0 ;k<Thread_Num;k++) { TCB[k].setvisit(0); } cout<<"-----------Priority:"<<endl; int i,j; int start = 0; float waittime = 0; float avwait = 0; for(i=1;i<Thread_Num;i++) { for(j=0;j<Thread_Num;j++){ if(TCB[j].getpriority()==i && TCB[j].getvisit()==0){ printf("Thread: %-2d Start: %-3d Runtime: %-2d\n",TCB[j].gettid(),start,TCB[j].getruntime()); waittime = waittime + (float)start; start = start + TCB[j].getruntime(); TCB[j].setvisit(1); } } } avwait = waittime / (float)Thread_Num; printf("Total waitting time : %f\n",waittime); printf("Average waitting time : %f\n",avwait);}//Main thread execute function to create 20 children threadsvoid *Children(void*){ int ret[Thread_Num]; t_init(); pthread_t tid[Thread_Num]; pthread_mutex_init(&Device_mutex,NULL); int i,j; for(i=0;i<Thread_Num;i++) { int k =i+1; ret[i] = pthread_create(&tid[i],NULL,&t_print, &k); if(ret[i] == 0) { sleep(1); } else{ printf("Thread_%-2d failed!\n",i+1); } } for(j=0;j<Thread_Num;j++) pthread_join (tid[i], NULL); pthread_mutex_destroy(&Device_mutex); pthread_exit(0);}int main(){ int ret1; pthread_t tid1;//Declare main thread ret1 = pthread_create(&tid1,NULL,&Children,NULL);//Create main thread if(ret1 == 0) { printf("Main Thread ok!\n"); sleep(20); } else{ printf("Thread failed!\n"); } FCFS(); SJF(); cout<<"Please enter RR time:\n";//Request RR time int rr; scanf("%d",&rr); RR(rr); Priority(); return 0;}
OK!此代码的运行结果如下(部分):
第一张图打印了一下虚拟PCB的部分内容:
第二张图片打印了FCFS调度算法运行结果:
第三张图片打印了SJF调度算法运行结果:
第四张图片打印了RR调度算法运行结果(部分):
第五张图片打印了Priority调度算法运行结果:
注意看每张图下面的两行数据,分别是不同算法对应的总的进程的等待时间以及平均等待时间的大小,印证了SJF算法通常是最少平均等待时间的调度算法
最后希望大家能够积极提建议,指出纰漏!
0 0
- Linux编程:模拟进程调度算法
- 进程调度模拟算法
- 模拟进程调度算法
- 进程调度模拟算法
- 模拟操作系统进程调度算法
- 【Linux】进程调度算法
- 【Linux】 进程调度算法
- Linux - 进程调度算法
- Linux 进程调度算法
- linux进程调度算法
- Linux进程调度算法
- LINUX 进程调度算法
- linux进程调度算法
- Linux进程调度算法
- linux进程调度器模拟
- 进程调度算法模拟程序设计C++
- 单处理器进程调度算法的模拟
- Linux 进程调度算法历史
- 细节决定成败
- 按之字形顺序打印二叉树
- spring data jpa 的坑
- malloc最大内存申请量
- 几种典型的立体匹配算法
- Linux编程:模拟进程调度算法
- Android自定义View
- WebService学习笔记(三) - JAXB与Stax
- 前/中序遍历序列重建二叉树
- 免费云笔记软件哪个好?
- bj
- C#笔记(语法层面)
- AngularJS—通过输入的值来改变样式
- 设计模式系列之六命令模式