Linux编程:模拟进程调度算法

一、“丑话”说在前头

稍稍有点操作系统基础的朋友应该知道进程的调度算法,在这里“所长”还是给大家略微介绍一下接下来要模拟的几种算法:

  1. 先来先服务(FCFS)
    采用FCFS调度,先请求CPU的进程会先分配到CPU。
    使用FCFS调度的等待时间通常较长,CPU利用率也会较低
  2. 最短作业优先调度(SJF)
    采用SJF调度会选择具有最短CPU运行时间的进程分配CPU使用权。如果两个进程的CPU区间相同,则按照FCFS来进行选择。
    SJF调度可以证明是最佳的,它降低了平均等待时间
  3. 轮转法调度(RR)
    RR调度将CPU时间分为较小的时间片,调度程序循环就绪队列。为每一个进程分配不超过一个时间片的CPU。
    RR调度专门用于分时系统
  4. 优先级调度
    每一个进程都有一个优先级与其关联,具有最高优先级的进程会分配到CPU。
    优先级调度的一个主要问题是优先级较低的进程会产生饥饿现象。

二、编程模拟

1. 思路整理

1.创建主线程,主线程创建子线程,子线程有一个虚拟PCB
2.主线程创建20个子线程,分别实现FCFS调度、SJF调度、RR调度、优先级调度,并且计算每个调度的平均等待时间。
3.对于每个子线程,在其运行期间,输出其占用的时间标号(例如,第3个线程占用了第10秒的CPU时间,输出为:“Thread3:10”)。

2. 代码(仅供参考)

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<pthread.h>
#include<time.h>
#include<iostream> 
#define Thread_Num 20
using 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 PCB
void 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 function
void *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 function
void 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 function
void 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 function
void 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 function
void 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 threads
void *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;
}


三、模拟运行结果

第一张图打印了一下虚拟PCB的部分内容:
这里写图片描述
第二张图片打印了FCFS调度算法运行结果:
这里写图片描述
第三张图片打印了SJF调度算法运行结果:
这里写图片描述
第四张图片打印了RR调度算法运行结果(部分):
这里写图片描述
第五张图片打印了Priority调度算法运行结果:
这里写图片描述

Note:每张图最下面的两行数据,分别是不同算法对应的总的进程的等待时间以及平均等待时间的大小,印证了SJF算法通常是最少平均等待时间的调度算法。

  • 9
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值