操作系统实验1-基于dos实现优先级的线程调度

        最近实验课老多。不过实验课当然比理论课好玩多了。关于实践和理论,我想说一句,只懂理论不懂实践,相当于左膀右避缺了一样。

        废话少说,步入正题。老师给了第一个版本的代码,是基于时间片轮转来进行线程调度的,我们的任务就是把调度算法改成基于优先级调度的程序。

       首先,我们要在struct TCB里面添加一个用于表示优先级的字段:int pri;

struct TCB{
	unsigned char *stack;
	unsigned  int ss;
	unsigned  int sp;
	int state;
	int pri;
	char name[10];
}tcb[NTCB];

       其次,初始化tcb[0], tcb[1], tcb[2]里面的pri值,tcb[0].pri 在main函数里面初始化为0; tcb[1].pri、tcb[2].pri在InitTCB里面初始化为50,100(这两个数值随便你们改,但不能为0)。

tcb[1].pri = 10; 
tcb[2].pri = 5;
tcb[0].pri = 0;


       另外,更改调度算法,即更改Find()函数,我们改为如下:

int Find()
{
	int i,max_pri,index;

	i = max_pri = index = 0;

	for( ; i < NTCB; i ++)
	{
		if(tcb[i].state != FINISHED && tcb[i].pri > max_pri)  // 如果某个线程执行完成,它的状态就会被over()设置成FINISHED
		{
			max_pri = tcb[i].pri;
			index = i;  // 保存最大优先级的下标
		}
	}

	return index; //返回最大优先级的下标,
}
         最后,就是特别坑的一行代码,在new_int8里面,要注释掉
if (i == current ) return;
为何要注释掉呢?你的线程若还没有执行完,就被中断调度了,那Find()返回的值是不是和current相等呢,答案是肯定的。那后面的timecount就不能被清零,那就下次中断来临时,if(timecount!=TIMESLIP)就永远不可能为真,线程就不能被调度了,懂?


最后 的最后,上修改过后的代码:

#include <dos.h>
#include <stdlib.h>


int current;
long timecount;
#define NTCB 3

#define FINISHED 0
#define RUNNING 1
#define READY   2
#define BLOCKED 3

#define TIMEINT 0x08

#define TIMESLIP 5

#define STACKLEN 1024

struct TCB{
	unsigned char *stack;
	unsigned  int ss;
	unsigned  int sp;
	int state;
        int pri;
	char name[10];
}tcb[NTCB];

void interrupt (*old_int8)(void);
void interrupt new_int8(void);
void interrupt test_int8(void);
void over(void);

#define GET_INDOS 0x34
#define GET_CRIT_ERR 0x5d06

char far *indos_ptr=0;
char far *crit_err_ptr=0;

int DosBusy(void);
void InitInDos(void);

void InitInDos(void)
{
 union REGS regs;
 struct SREGS segregs;

 regs.h.ah=GET_INDOS;
 intdosx(&regs, &regs, &segregs);
 indos_ptr=MK_FP(segregs.es, regs.x.bx);


 if(_osmajor<3)
   crit_err_ptr=indos_ptr+1;
 else if(_osmajor==3&&_osminor==0)
   crit_err_ptr=indos_ptr-1;
 else
 {
   regs.x.ax=GET_CRIT_ERR;
   intdosx(&regs, &regs, &segregs);
   crit_err_ptr=MK_FP(segregs.ds, regs.x.si);
 }
}

int DosBusy(void)
{
 if(indos_ptr&&crit_err_ptr)
   return(*indos_ptr||*crit_err_ptr);
 else
   return -1;
}

typedef void (far *funcptr)(void);
int create(char *name, funcptr func, int stlen);



void p1( )
{
	long i, j, k;

	for(i=0; i<40; i++)
	{
		putchar('a');

		for(j=0; j<1000; j++)
			for(k=0; k<20000; k++);
	}
}

void p2( )
{
	long i, j, k;

	for(i=0; i<20; i++)
	{
		putchar('b');

		for(j=0; j<1000; j++)
			for(k=0;k<20000; k++);
	}
}

int Find()
{
	int i,max_pri,index;

	i = max_pri = index = 0;

	for( ; i < NTCB; i ++)
	{
		if(tcb[i].state != FINISHED && tcb[i].pri > max_pri)
		{
			max_pri = tcb[i].pri;
			index = i;
		}
	}

	return index;
}

void interrupt swtch()            /* 其他原因CPU调度  */
{
	int i;

	if(tcb[current].state!=FINISHED
		&¤t!=0) /* 当前线程还没结束 */
		return;

	i=Find();
	if(i<0)
		return;

	disable();
	tcb[current].ss=_SS;
	tcb[current].sp=_SP;

	if(tcb[current].state==RUNNING)
		tcb[current].state=READY;      /* 放入就绪队列中 */

	_SS=tcb[i].ss;
	_SP=tcb[i].sp;        /* 保存现场 */

	tcb[i].state=RUNNING;
	current=i;
	enable();
}

void over()
{
	if(tcb[current].state==RUNNING)
	{
		disable();
		tcb[current].state=FINISHED;
		strcpy(tcb[current].name,NULL);
		free(tcb[current].stack);
		enable();
	}

	swtch();
}

void InitTcb()
{
	unsigned int *tmp=0;

	//for thread 1

	tcb[1].state=READY;
        tcb[1].pri = 10;
//	strcpy(tcb[1].name, "p1");

	tcb[1].stack=(unsigned char *)malloc(STACKLEN);
	memset(tcb[1].stack, 0xff, STACKLEN);

	tmp=(unsigned int *)(tcb[1].stack+STACKLEN-2);
	
	*tmp=FP_SEG(over);
	*(tmp-1)=FP_OFF(over);
	*(tmp-2)=0x200;	
	*(tmp-3)=FP_SEG(p1);
	*(tmp-4)=FP_OFF(p1);
	
	*(tmp-9)=_ES;
	*(tmp-10)=_DS;
	tcb[1].ss=FP_SEG(tmp-13);
	tcb[1].sp=FP_OFF(tmp-13);


	//for thread 2

	tcb[2].state=READY;
        tcb[2].pri = 5;
//	strcpy(tcb[2].name, "p2");

	tcb[2].stack=(unsigned char *)malloc(STACKLEN);
	memset(tcb[2].stack, 0xff, STACKLEN);
	
	tmp=(unsigned int *)(tcb[2].stack+STACKLEN-2);

	*tmp=FP_SEG(over);
	*(tmp-1)=FP_OFF(over);
	*(tmp-2)=0x0200;	
	*(tmp-3)=FP_SEG(p2);
	*(tmp-4)=FP_OFF(p2);
	
	*(tmp-9)=_ES;
	*(tmp-10)=_DS;
	tcb[2].ss=FP_SEG(tmp-13);
	tcb[2].sp=FP_OFF(tmp-13);
}

void interrupt new_int8(void)
{
	int i;

	(*old_int8)();
	timecount++;

	if(timecount!=TIMESLIP)
		return;
	else
	{
		if(DosBusy())
			return;
		else
		{
			disable();
//			asm CLI

			tcb[current].ss=_SS;
			tcb[current].sp=_SP;

			if(tcb[current].state==RUNNING)
				tcb[current].state=READY;

			i=Find();

			//if(i==current)
			//	return;

			
			_SS=tcb[i].ss;
			_SP=tcb[i].sp;
			tcb[i].state=RUNNING;

			timecount=0;
			current=i;

			enable();
//			asm STI

		}
	}
}


void tcb_state()
{
	int i;

	for(i=0; i<NTCB; i++)
	{
		switch(tcb[i].state)
		{
		case FINISHED:
				printf("\nthe thread %d is finished!\n", i);
				break;
		case RUNNING:
				printf("the thread %d is running!\n", i);
				break;
		case READY:
				printf("the thread %d is ready!\n", i);
				break;
		case BLOCKED:
				printf("the thread %d is blocked!\n", i);
				break;
		default:
				printf("unknown state of thread %!\n", i);
		}
	}
}

int all_finished()
{
	int i;

	if(tcb[1].state!=FINISHED||tcb[2].state!=FINISHED)
		return -1;
	else 
		return 0;
}

void releaseTcb()
{
	int i=0;

	for(i=1; i<NTCB; i++)
	{
		if(tcb[i].stack)
			free(tcb[i].stack);
	}
}

void main()
{
	timecount=0;

	InitInDos();
	InitTcb();

	old_int8=getvect(TIMEINT);

	strcpy(tcb[0].name, "main");
	tcb[0].state=RUNNING;
        tcb[0].pri = 0;
	current=0;

	tcb_state();

	disable();
	setvect(TIMEINT, new_int8);
	enable();

	while(all_finished())
	{
	//	printf("system running!\n");	
	}


	tcb[0].name[0]='\0';
	tcb[0].state=FINISHED;
	setvect(TIMEINT, old_int8);

	tcb_state();

	printf("\n Multi_task system terminated.\n");
}


好了,至此代码完成。

运行结果p1,p2输出为aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbb

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值