【模拟+数据结构】操作系统

本文介绍了一个模拟操作系统进程调度的程序实现。程序通过处理输入文件中的进程数据,模拟单CPU环境下进程的执行情况,包括进程的到达、执行及优先级调度等关键特性。

第二题:操作系统

(sys.exe)

 

写一个程序来模拟操作系统的进程调度。假设该系统只有一个CPU,每一个进程的到达时间,执行时间和运行优先级都是已知的。其中运行优先级用自然数表示,数字越大,则优先级越高。

如果一个进程到达的时候CPU是空闲的,则它会一直占用CPU直到该进程结束。除非在这个过程中,有一个比它优先级高的进程要运行。在这种情况下,这个新的(优先级更高的)进程会占用CPU,而老的只有等待。

如果一个进程到达时,CPU正在处理一个比它优先级高或优先级相同的进程,则这个(新到达的)进程必须等待。

一旦CPU空闲,如果此时有进程在等待,则选择优先级最高的先运行。如果有多个优先级最高的进程,则选择到达时间最早的。

输入格式:

l        输入文件名:sys.in

l        输入文件包含若干行,每一行有四个自然数(均不超过108),分别是进程号,到达时间,执行时间和优先级。不同进程有不同的编号,不会有两个相同优先级的进程同时到达。输入数据已经按到达时间从小到大排序。输入数据保证在任何时候,等待队列中的进程不超过15000个。

输出格式:

l        输出文件名:sys.out

l        按照进程结束的时间输出每个进程的进程号和结束时间。

输入输出示例:

sys.in

1 1 5 3

2 10 5 1

3 12 7 2

4 20 2 3

5 21 9 4

6 22 2 4

7 23 5 2

8 24 2 4

sys.out

1 6

3 19

5 30

6 32

8 34

4 35

7 40

2 42


就是一个模拟,加上堆,思路很简单,只是中间的细节要考虑仔细。

我的想法是,既然当前的任务只能有一个,那么我就用i,s,t,l四个变量表示即可。

而未到来的任务暂时不用考虑。而之前中断的任务,放到一个堆中表示待办任务。


考虑一个任务完成时:

如果堆中还有任务剩余,就把它取出来继续做,时间不改变。(注意这里如果对输入不进行处理,这条任务就被忽略掉了,应该把它放回缓冲区)

如果堆中没有剩余,则把新进入的任务拿来做,时间直接跳跃到新任务的起始时间。

当新来了一个任务,而当前任务不能够完成:

如果新任务的等级高:我们把剩余的时间减少,并把它放入堆中。修改当前时间为新的开始时间,并处理新任务

如果当前任务等级高:我们直接把新任务放入堆中。

另外要考虑的是,当没有新任务进来的时候:

我们先把当前任务处理完,然后依次把堆中的任务处理完。



本以为自己已经细心再细心不能更细心了,结果,还是被3个犯二的错给坑了。

提交次数:4

1、如果前一个认为在t时课完成,下一个任务就可以在t时刻开始,而不用等到t+1时刻。

2、手动的输入缓冲区开小了,只开了100,我以为这个东西根本用处不大,结果直开到了1000000才终于过的。

3、堆中首先按等级的降序排,再按进入时间的升序排。一开始把进入时间弄成了剩余时间,然后又弄成了降序。。。

于是我明白,没有最仔细,只有更仔细。


#include <queue>
#include <cstdio>

struct task
{
	long i,s,t,l;
	bool operator<(const task& t2)const
	{
		if (l == t2.l)
			return s>t2.s;
		return l<t2.l;
	}
	task(long ii,long ss,long tt,long ll):i(ii),s(ss),t(tt),l(ll){}
	task(){}
};

using std::priority_queue;
priority_queue<task> heap;

long floati[1000000];
long floats[1000000];
long floatt[1000000];
long floatl[1000000];
long fl = 1;
long fr = 1;

int main()
{
	freopen("sys.in","r",stdin);
	freopen("sys.out","w",stdout);
	long i=0,s=-1,t=10000000,l=-1;
	long ni,ns,nt,nl;
	long last = 0;
	task now;
	while (1)
	{
		if (fl < fr)
		{
			fl++;
			ni = floati[fl];
			ns = floats[fl];
			nt = floatt[fl];
			nl = floatl[fl];
		}
		else
		{
			if(scanf("%ld%ld%ld%ld",&ni,&ns,&nt,&nl) <= 0)
				break;
		}
		if (ns >= last+t)
		{
			printf("%ld %ld\n",i,last+t);
			if (!heap.empty())
			{
				fr ++;
				floati[fr] = ni;
				floats[fr] = ns;
				floatt[fr] = nt;
				floatl[fr] = nl;
				last = last+t;
				now = heap.top();
				heap.pop();
				i = now.i;
				s = now.s;
				t = now.t;
				l = now.l;
			}
			else
			{
				i = ni;
				s = ns;
				t = nt;
				l = nl;
				last = ns;
			}
			continue;
		}
		t -= ns-last;
		last = ns;
		if (nl > l)
		{
			if (s > 0)
			{
				heap.push(task(i,s,t,l));
			}
			i = ni;
			s = ns;
			t = nt;
			l = nl;
		}
		else
		{
			heap.push(task(ni,ns,nt,nl));
		}
	}
	printf("%ld %ld\n",i,last+t);
	last += t;
	while (!heap.empty())
	{
		now = heap.top();
		printf("%ld %ld\n",now.i,last+now.t);
		heap.pop();
		last = last+now.t;
	}
	return 0;
}



实验内容: 编一个单处理机下的进程调度程序模拟操作系统进程调度。 要求: 能够创建指定数量的进程,每个进程一个进程控制块表示。 实现先来先服务调度算法:进程到达间可由进程创建间表示。 实现短作业优先调度算法:可指定进程要求的运行间。(说明:对不可剥夺的短作业优先算法,当作业运行间相等,优先调度进程号小的进程执行;对可剥夺式的短作业优先算法,即选最短剩余间的进程进行运行,在剩余间相同的情况下,选择到达间早的进程进行运行) 实现间片轮转调度算法:可指定生成间片大小。(说明:新进程到来插入到就绪队列的队尾,当进程P运行完一个间片,若同进程Q到达,则先在就绪队列队尾插入新到达进程Q,之后再插入进程P) 实现动态优先级调度算法:可指定进程的初始优先级(优先级与优先数成反比,优先级最高为0),优先级改变遵循下列原则:进程在就绪队列中每停留一个间片,优先级加1,进程每运行一个间片,优先级减3。(说明:本算法在优先级相同的情况下,选择到达间早的进程进行运行) 测试用例格式如下: 输入:调度算法    进程号/到达间/运行间/优先级/间片 输出:调度顺序/进程号/开始运行间/结束运行间/优先级 其中调度算法选项为:1----先来先服务,2----短作业优先,3----最短剩余间优先,4----间片轮转,5----动态优先级
一个单处理机下的进程调度程序模拟操作系统进程调度。 要求: 1.能够创建指定数量的进程,每个进程一个进程控制块表示。 2.实现先来先服务调度算法:进程到达间可由进程创建间表示。 3.实现短作业优先调度算法:可指定进程要求的运行间。(说明:对不可剥夺的短作业优先算法,当作业运行间相等,优先调度进程号小的进程执行;对可剥夺式的短作业优先算法,即选最短剩余间的进程进行运行,在剩余间相同的情况下,选择到达间早的进程进行运行) 4. 实现间片轮转调度算法:可指定生成间片大小。(说明:新进程到来插入到就绪队列的队尾,当进程P运行完一个间片,若同进程Q到达,则先在就绪队列队尾插入新到达进程Q,之后再插入进程P) 5.实现动态优先级调度算法:可指定进程的初始优先级(优先级与优先数成反比,优先级最高为0),优先级改变遵循下列原则:进程在就绪队列中每停留一个间片,优先级加1,进程每运行一个间片,优先级减3。(说明:本算法在优先级相同的情况下,选择到达间早的进程进行运行) 测试用例格式如下: 输入:调度算法    进程号/到达间/运行间/优先级/间片 输出:调度顺序/进程号/开始运行间/结束运行间/优先级 其中调度算法选项为:1----先来先服务,2----短作业优先,3----最短剩余间优先,4----间片轮转,5----动态优先级
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值