操作系统--进程调度(C语言)

#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<malloc.h>
 
using namespace std;
 
struct PCB_type
{
	int pid;		//进程名
	int state;		//进程状态	2--表示"执行"状态	 1--表示"就绪"状态	0--表示"阻塞"状态
	int cpu_time;	//运行需要的cpu时间(需运行的时间片个数)               
};
 
typedef struct QueueNode			//队列链表
{
	struct PCB_type PCB;
	struct  QueueNode  *next;
}*QueueLink;
 
 
//设置全程变量
struct QueueNode	*ready_head=NULL,       //ready队列队首指针
					*ready_tail=NULL ,       //ready队列队尾指针
					*blocked_head=NULL,    //blocked队列队首指针
					*blocked_tail=NULL;     //blocked队列队尾指针
 
 
int t;		//定义一个全局变量个时间片系统释放资源,唤醒处于阻塞队列队首的进程
 
//设置相应的子程序
void start_state()  //读入假设的数据,设置系统初始状态
{
	int i,n,m;				//用来计数循环
	QueueLink p,p1,p2;		//一个节点指针
	printf("输入n个进程处于就绪状态,m个进程处于阻塞状态,且每过t个时间片系统释放资源,唤醒处于阻塞队列队首的进程。");
	scanf("%d,%d,%d",&n,&m,&t);
	//创建链表
	//创建一个节点
	p1=(QueueLink)malloc(sizeof(QueueNode));		//以免ready和blocked指向相同
	p2=(QueueLink)malloc(sizeof(QueueNode));
	p1->next=NULL;
	p2->next=NULL;
	
//初始化就绪队列全程变量
	ready_head=ready_tail=p1;
	//吧ready队列链表创建好
	for(i=0 ; i<n ; i++)
	{
		p=(QueueLink)malloc(sizeof(QueueNode));
		p->next=NULL;
		p->PCB.state=1;			//进程状态	2--表示"执行"状态	 1--表示"就绪"状态	0--表示"阻塞"状态
		printf("亲!请输入第 %d 个就绪进程的进程名和进程时间:",i+1);
		scanf("%d,%d",&p->PCB.pid,&p->PCB.cpu_time);
	//	cout<<p->PCB.pid<<endl;
		ready_tail->next=p;		//把p加入表尾
		ready_tail=p;			//吧表尾指针指向新的表尾
	}
 
//初始化阻塞队列的全程变量
	blocked_head=blocked_tail=p2;
	//吧blocked队列链表创建好
	for(i=0 ; i<m ; i++)
	{
		p=(QueueLink)malloc(sizeof(QueueNode));
		p->next=NULL;
		p->PCB.state=0;	//进程状态	2--表示"执行"状态	 1--表示"就绪"状态	0--表示"阻塞"状态
		printf("亲!请输入第 %d 个阻塞队列的进程名和进程时间:",i+1);
		scanf("%d,%d",&p->PCB.pid,&p->PCB.cpu_time);
	//	cout<<"ddddddddddd"<<endl;
		blocked_tail->next=p;			//吧p加入阻塞队列的表尾
		blocked_tail=p;			//吧表尾指针指向新的表尾
	}
 
}
 
float use_cpu=0,unuse_cpu=0;	//use_cpu记录cpu运行时间,unuse_cpu记录CPU空闲时间,x用来计数是否该唤醒阻塞队列了
 
void dispath( )     //模拟调度
{
	int x=0; 
	QueueLink p;			//指针用于指向队列的位置
		while(ready_head!=ready_tail || blocked_head!=blocked_tail)		//判断ready队列或block队列不为空
		{
			if(ready_head!=ready_tail)		//判断就绪队列不为空
			{
				//取出ready队列的队首节点
				p=ready_head->next;
				p->PCB.state=2;		//开始执行
				printf("当前正在执行的PCB名称是:%d   ",p->PCB.pid);
				p->PCB.cpu_time--;		//需要的时间减少,这里是表示每个进程的时间片是1
				use_cpu++;
				if(ready_head->next != ready_tail)		//判断是否只剩下一个节点了
				{
					if(p->PCB.cpu_time > 0)		//判断时间是否够了,程序执行完成
					{
						ready_head->next=p->next;		//吧队首向后移动一位
						//吧原来的队首放到队尾
						ready_tail->next=p;
						ready_tail=p;		//队尾指向新的节点
						p->next=NULL;		//吧队尾重置为空
						p->PCB.state=1;
					}
					else
					{
						//cout<<"sssssssss"<<endl;
						ready_head->next=p->next;
						printf("  进程%d完成  ",p->PCB.pid);
						p->next=NULL;
						free(p);
					}
				}
				else
				{
					if(p->PCB.cpu_time <= 0)
					{
						ready_tail=ready_head;		//链队列为空,头尾连到一起
						printf("  进程%d完成  ",p->PCB.pid);
						p->next=NULL;
						free(p);
					}}
			}
			else				//进程状态	2--表示"执行"状态	 1--表示"就绪"状态	0--表示"阻塞"状态
			{
				unuse_cpu++;
				printf("时间片轮空一回!         ");
			}
			x++;		//执行过后吧用掉的时间加上,这里每次为一
			if(x==t && blocked_head != blocked_tail)		//到时候向就绪队列送节点,且阻塞队列不为空
			{
				if(blocked_head->next != blocked_tail)
				{
					p=blocked_head->next;
					printf("  唤醒进程%d",p->PCB.pid );
		        	blocked_head->next=p->next;		//吧阻塞队列头指针指向下一个
					ready_tail->next=p;
					ready_tail=p;		//指向新的队尾
					p->next=NULL;
			//		printf("xxxxxx\n");			
					x=0;		//把x重新赋值为零
				}
				else		//如果是只剩下最后一个节点
				{
					p=blocked_head->next;
					printf("  唤醒进程%d",p->PCB.pid );
					blocked_tail=blocked_head;		//吧头尾指针指向一起
					ready_tail->next=p;
					ready_tail=p;		//指向新的队尾
					p->next=NULL;
				}
			}
			printf("\n");
		} 
} 
 
void calculate()    //计算CPU利用率
{
	float rate;		//CPU利用率
	rate=use_cpu/(use_cpu+unuse_cpu);
	printf("CPU利用率是:%f\n",rate);
 
}
 
void main()
{ 
	start_state();

//	cout<<ready_head->PCB.pid<<endl;
 	dispath(); 
	calculate(); 
}
  • 2
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值