操作系统,进程调度之时间片轮转算法

操作系统,进程调度之时间片轮转算法

命名是中英混名(英语不好),第一次分享代码,如果有不好的地方还请指出。

typedef struct PCB
{
	char Name;//进程名
	int Arrivetime;//到达时间
	int Servertime;//服务时间
	int Front;//优先级
	int Starttime;//开始时间
	int Finishtime;//完成时间
	float Wholetime;//周转时间
	float Valuewholetime;//带权周转时间
	int Ago;//是否被访问标记
	struct PCB *next;
	int Shenyutime;//剩余时间
	int Zdtime;//中断时间
}_PCB;
_PCB *head;
_PCB *creat()//创建并输入链表
{
	char c;
	int a=0, b=0,yxj=0;
	PCB *p1,*p2;
	head= (PCB*)malloc(LEN);
	head->next=NULL;
	p1 = head;
	while (true)
	{
		p2 = (PCB*)malloc(LEN);
		printf("进程名 到达时间 服务时间 优先级(全为0结束)\n");
		scanf_s("%c %d %d %d", &c,sizeof(c),&a, &b,&yxj);
		getchar();
		if (a == 0 && b == 0) {
			p2->next = NULL;
			break;
		}//其实中间两个为0就结束了
		else {//各种初始化和录入信息
			p2->Ago = 0;
			p2->Starttime = 0;
			p2->Finishtime = 0;
			p2->Front = yxj;
			p2->Name = c;
			p2->Arrivetime = a;
			p2->Zdtime = a;
			p2->Servertime = b;
			p2->Shenyutime = b;
			p2->next = NULL;
			p1->next = p2;
			p1 = p2;
		}
	}
	return head;
}
void Sort(_PCB *&l) { //采用头插法,使用先到先服务排序
	_PCB* p = l->next, * pre;
	_PCB* r = p->next;
	p->next = NULL;
	p = r;
	while (p != NULL) {
		r = p->next;
		pre = l;
		while (pre->next != NULL && pre->next->Arrivetime < p->Arrivetime) {
			pre = pre->next;
		}
		p->next = pre->next;
		pre->next = p;
		p = r;
	}
}
_PCB* sjplz(int n,_PCB *l) {
	_PCB *h,*a,*b,*c,*d;
	h = l;
	b = h->next;
	a = b;
	int p = 0;
	b->Starttime = b->Arrivetime;//第一个到达时间就是第一个进程的开始时间
	p = b->Arrivetime;
	printf("进程\t到达时间\t服务时间\t开始时间\t完成时间\t剩余时间\t执行次数\t当前时间\n");
	while (b)
	{
		c = b->next;
		if (b->Starttime == 0 && b->Ago == 0)b->Starttime = p;//判断进程是否执行过,计算进程开始时间
		if (b->Shenyutime <= n) {//判断剩余时间
			if (b->Ago!=0) {//是否执行过
				b->Finishtime = b->Shenyutime + p;
				p = p + b->Shenyutime;
				b->Shenyutime = 0;
				b->Ago++;
				printf("%c\t%d\t\t%d\t\t%d\t\t%d\t\t%d\t\t%d\t\t%d\n", b->Name, b->Arrivetime, b->Servertime, b->Starttime, b->Finishtime, b->Shenyutime, b->Ago, p);
			}else {
				if (b->Arrivetime > p ) {
					b->Starttime = b->Arrivetime;//如果进程开始前存在系统空闲,开始时间即该进程到达时间
				}
				else
				{
					b->Starttime = p;//开始时间是当前系统时间
				}
				b->Finishtime = b->Shenyutime + p;//计算完成时间
				p = p + b->Shenyutime;
				b->Ago++;
				b->Shenyutime = 0;
				printf("%c\t%d\t\t%d\t\t%d\t\t%d\t\t%d\t\t%d\t\t%d\n", b->Name, b->Arrivetime, b->Servertime, b->Starttime, b->Finishtime, b->Shenyutime, b->Ago, p);
			}
		}else {
			b->Shenyutime = b->Shenyutime - n;//一次时间片内未完
			p = p + n;
			b->Zdtime = p;//记录中断时间
			b->Ago++;
			printf("%c\t%d\t\t%d\t\t%d\t\t%d\t\t%d\t\t%d\t\t%d\n", b->Name, b->Arrivetime, b->Servertime, b->Starttime, b->Finishtime, b->Shenyutime, b->Ago, p);
			if (c!=NULL) {
				
				int i = 0;
				int j=0;
				while (c)
				{
					if (c->Arrivetime > p || b->Zdtime > p) {//寻找该进程下一次进入就绪序列的位置
						if (i == 0) {
							l->next = b->next;
							b = l;
							j = 1;
							break;						
						}
						else
						{
							
							l->next = b->next;
							a->next = b;
							b->next = c;				
							b = l;
							j = 1;
						}
						break;
					}
					a = c;
					c = c->next;
					i++;
				}
				if (j == 0) {//未找到比该进程更晚进入的进程,接入链尾
					l->next = b->next;

					a->next = b;
					b->next = NULL;
					b = l;
				}
			}else {//就绪队列仅剩一个,持续执行该进程直至完成
				l->next = b;
				b->next = NULL;
				b = l;
			}
		}
		d = b;
		b = b->next;
	}
	return l;//传出来的头指针与原链表不同,会丢失数据,但是不影响中间计算过程。
}
int main()
{
	_PCB* k;
	k = creat();
	int s;
	Sort(k);
	printf("输入时间片长度\n n=");
	scanf_s("%d",&s);
	k=sjplz(s,k);
	return 0;
}

图片: 输入样式
输出样式

(1)、假定系统有五个进程,每一个进程用一个进程控制块PCB来代表。进程控制块的格式 (2)、每次运行你所设计的处理器调度程序之前,为每个进程任意确定它的“要求运行时间”。 把五个进程按顺序排成循环队列,用指针指出队列连接情况。另用一标志单元记录轮到运行的进程。 (3)、处理器调度总是选择标志单元指示的进程运行。由于本实验是模拟处理器调度的功能,所以,对被选中的进程并不实际启动运行 (4)、进程运行一次后,应把该进程的进程控制块中的指针值送到标志单元,以指示下一个轮到运行的进程。同时,应判断该进程的要求运行时间与已运行时间,若该进程要求运行时间≠已运行时间,则表示它尚未执行结束,应待到下一轮时再运行。若该进程的要求运行时间=已运行时间,则表示它已经执行结束,应把它的状态修改为“结束”(E)且退出队列。此时,应把该进程的进程控制块中的指针值送到前面一个进程的指针位置。 (5)、若“就绪”状态的进程队列不为空,则重复上面(4)和(5)的步骤,直到所有进程都成为“结束”状态。 (6)、在所设计的称序中应有显示或打印语句,能显示或打印每次被选中进程的进程名以及运行一次后进称对列的变化。 (7)、为五个进程任意确定一组“要求运行时间”,启动所设计的处理器调度程序,显示或打印逐次被选中进程的进程名以及进程控制块的动态变化过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值