多任务系统-课程设计-杭电_第1页
多任务系统-课程设计-杭电_第2页
多任务系统-课程设计-杭电_第3页
多任务系统-课程设计-杭电_第4页
多任务系统-课程设计-杭电_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、多任务系统-课程设计-杭电操作系统课程设计报告小组编号:小组成员:一、课程设计概述:1、题目:基于DOS的多任务系统的实现2、实现 1程序的设计思想以及各个功能的实现思想:该程序主要是分5大块内容:线程的创立和撤销,线程的调度,线程的同步与互斥,线程的阻塞与唤醒,利用消息缓冲队列的线程间的通信。由这五大块功能来完成的基于DOS的多任务系统的实现。在这个系统中,首先先由main函数进行一些初始化工作,然后直接创立0#线程对应于main函数,再由0#线程调用create创立1#,2#线程分别对应与函数f1(),f2(),最后将系统的中断效劳程序设置为new_int8,并把控制交给1#线程,启动多个

2、线程的并发执行。 0#线程是一个比拟特殊的线程,它在创立的时候没有使用create来创立,而是在系统初始化后直接创立的,因它对应的程序段为main函数中的一段,所以也直接使用整个系统的堆栈,而不再创立时为私有堆栈分配额外的空间;同样,撤销的时也不需要释放私有堆栈的空间,所以也没有over()函数而是直接撤销,从这方面来看,它是一个系统线程。此外,在启动多个线程并发执行过程后,0#线程将系统控制权转交出去,直至系统中其他进程都不具备执行条件时,它才有可能重新得到CPU,从这方面看,0#线程相当于是一个空转线程,最后,0#线程还担负着一个特别的使命:等待系统中所有其他的线程的完成,此时,它将直接撤

3、销自己并恢复原来的时钟中断效劳程序,从此终止整个多任务系统。a.线程的创立和撤销线程的创立过程关键就是对私有堆栈和TCB初始化的过程,其过程如下: i, 为新线程分配一空闲的线程控制块ii, 为新线程的私有堆栈分配内存空间因为对等线程共享程序段和数据段空间,所以创立线程时不必像创立进程那样再为程序段和数据段分配内存空间iii, 初始化新线程的私有堆栈,即按CPU调度时现场信息的保存格式布置堆栈。iv, 初始化线程控制块,即填入线程的外部标识符,设置好线程私有堆栈的始址,段址和栈顶指针,将线程的状态置为就绪状态。v, 最后,返回新线程的内部标识符vi, 线程的内存映像如下:低地址)59a:63e

4、的返回地址:59ba:a3e线程的撤销过程中,一个关键的地方是在初始化线程私有堆栈时 需要将over()的入口地址压入线程的私有堆栈中,这样做的好处是:当线程所对应的函数正常结束时,over()函数的入口地址将最为函数的返回地址被弹出至CS,IP存放器,那么控制将自动转向over(),从而使对应的线程被自动撤销,并重新进行CPU调度。 b.线程的调度引起CPU调度原因主要是有三种情况:时间片到时,线程执行完毕或正57f7:87957f7:4b6在执行的线程因等待某种事件而不能继续执行。由这些原因,调度程序可以通过两个函数分别处理不同原因引起的调度: New_int8()函数主要是处理因时间片到

5、时引起的调度该调度可以通过截取时钟中断int 08来完成;Swtch()函数主要是处理因其他原因引起的调度;New_int8()函数因为是通过截取时钟中断来实现,可以知道其是属于系统调度,由于涉及到系统调度的函数 都是需要对DOS状态进行判断,以防止出现系统数据混乱等情况的发生从Dos的不可重入性来得出,而Swtch()函数是处理因其他原因引起的调度,所以它所涉及到的仅仅是用户级的函数调度,没有涉及到系统级的函数调度,因此Swtch()函数不需要对Dos状态进行判断。对于线程的两种调度函数的过程,因其相似,给出New_int8()函数的执行过程图,如下: 需要主要的是:新的时钟中断处理程序不能

6、太长,否那么系统效率将大大下降甚至使系统无法正常工作;在新的时钟中断处理程序必须调用系统原来的INT 08H,否那么将影响磁盘马达的关闭和系统的计时,另外,我们还主要依赖原来的INT 08H向中断控制器发中断结束指令EOI; c.线程的阻塞与唤醒线程的阻塞:主要是当某一线程需要阻塞的时候,将其插入阻塞队列中,等待唤醒进程唤醒,所以其过程为:首先,将线程的状态置为阻塞态,然后将线程插入指定的阻塞队列末尾,并重新进行CPU调度。 线程的唤醒:主要是唤醒阻塞队列里面的线程,所以其过程是:把阻塞队列头上的第一个线程的TCB取下来,并将其状态改为就绪状态,等待CPU调度.d.线程的同步与互斥在这个系统中

7、是采用记录型信号量机制来实现同步与互斥的,实现的方法:采用P ,V操作,设置两个信号量:一个为互斥信号量,一个为临界资源数目;e.利用消息缓冲队列的线程间通信线程间的通信,关键采用send()与receive()来实现,通过发送一个文本信息来显示通信的过程,其过程为:send()函数:消息的发送者需要提供接收者的标识符,消息的长度以及消息正文的起始地址等信息,然后在发送原语里申请一空闲的消息缓冲区,用相应的信息来装配该消息缓冲区,并把它插入到接收者的消息队列中去。Receive()函数:消息的接受者必须给出发送者的标识符,接受区的起始地址等信息,然后从自己的消息队列中取得相应的发送者发送来的消

8、息缓冲区,将消息正文复制到接受区中,并释放相应的消息缓冲区。 2程序的流程图: 三、程序实现代码:#include <alloc.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <dos.h> #define FINISHED 0 #define RUNNING 1#define READY 2#define BLOCKED 3 #define NTCB 10#defin

9、e NTEXT 20#define NBUF 5 #define NSTACK 1024#define GET_INDOS 0x34#define GET_CRIT_ERR 0x5d06char far *indos_ptr = 0; char far *crit_err_ptr = 0; int timecount = 0;int TL;int current = -1;int n = 0; typedef int (far *codeptr)(void); void interrupt(*old_int8)(void);/* 记录型信号量 */typedef structint value

10、;struct TCB *wq; semaphore; semaphore mutex = 1, NULL; semaphore mutexfb = 1, NULL; semaphore sfb = NBUF, NULL; semaphore empty = NBUF, NULL; semaphore full = 0, NULL;/* 消息缓冲区 */struct bufferint id;int size;char textNTEXT;struct buffer *next;bufNBUF, *freebuf; struct TCBunsigned char *stack;unsigned

11、 ss;unsigned sp;char state;char nameNTEXT;struct buffer *mq;semaphore mutex;semaphore sm;struct TCB *next; tcbNTCB; struct int_regsunsigned bp, di, si, ds, es, dx, cx, bx, ax, ip, cs, flags, off, seg; ; int intbufNBUF, buftemp;int in = 0, out = 0; void over();void destroy(int id);void wait(semaphore

12、 *sem);void signal(semaphore *sem);void block(struct TCB *qp);void wakeupFirst(struct TCB *qp);void send(char *receiver, char *a, int size);int receive(char *sender, char *b); void InitDos(void)union REGS regs;struct SREGS segregs;regs.h.ah = GET_INDOS;intdosx(&regs, &regs, &

13、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;elseregs.x.ax = GET_CRIT_ERR;intdosx(&regs, &regs, &segregs);crit_err_ptr = MK_FP(segregs.ds

14、, regs.x.si); /* DosBusy(): 函数功能是获得Indos标志及严重错误标志的值,判断是否dos忙; */* 如果返回值是1,表示dos忙; */* 如果返回值是0,表示dos不忙; */* 如果返回值是-1,表示还没有调用InitDos() */int DosBusy(void)if(indos_ptr && crit_err_ptr)return (*indos_ptr | *crit_err_ptr);elsereturn -1; /* InitDos() hasnt been called */ /* 初始化tcb */void i

15、nitTCB()int i;for(i = 0; i < NTCB; i+)0 = 0;tcbi.stack = NULL;tcbi.state = FINISHED;tcbi.mq = NULL;tcbi.mutex.value = 1;tcbi.mutex.wq = NULL;tcbi.sm.value = 0;tcbi.sm.wq = NULL;tcbi.next = NULL; void f1(void)long i,j,k;for(i=0;i<10;i+)putchar(a);for(j=0;j<1000;j+)for(k=

16、0;k<100;k+); void f2(void)long i,j,k;for(i=0;i<8;i+)putchar(b);for(j=0;j<1000;j+)for(k=0;k<100;k+); void f3(void)long i,j,k;for(i=0;i<6;i+)putchar(c);for(j=0;j<1000;j+)for(k=0;k<100;k+); void f4()int i;for(i = 0; i < 10; i+) wait(&mutex

17、); n+;printf(" %d", n); signal(&mutex); sleep(1); void f5()int i;for(i = 0; i < 5; i+) wait(&mutex); n-;printf(" %d ", n); signal(&mutex); sleep(1); void prdc()int tmp, i;for(i = 1; i <= 10; i+)tmp = i ;printf("prdc %

18、dn", tmp); wait(&empty);wait(&mutex);intbufin = tmp;in = (in + 1) % NBUF; /*printf("in: %dn", in);*/ signal(&mutex);signal(&full); void cnsm()int tmp, i;for(i = 1; i <= 10; i+)wait(&full);wait(&mutex);tmp = intbufout;o

19、ut = (out + 1) % NBUF; /*printf("out: %dn", out);*/ signal(&mutex);signal(&empty);printf("Out %d: %dn", i, tmp); sleep(2); void sender(void)int i,j;char a10;loop:for(i=0;i<10;i+)strcpy(a,"message"); a7=0+n;a8=0;send(&qu

20、ot;receiver",a,strlen(a);printf("sender:Message "%s" has been sentn",a);n+;receive("receiver",a);if (strcmp(a,"ok")!=0)printf("Not be committed,Message should be resended!n");/*接收进程没确认,需重新发送消息*/goto lo

21、op;elseprintf("Committed,Communication is finished!n");/*发送者得到接收者确实认,通信结束*/ void receiver(void)int i,j,size;char b10;for(i=0;i<10;i+)b0=0;while(size=receive("sender",b)=-1);printf("receiver: Message is received-");for(j=0;j<size;j+)

22、putchar(bj);printf("n");strcpy(b,"ok");send("sender",b,3);/* 发送确认消息 */ int create(char *name, codeptr code, int stck)struct int_regs far *r;int i, id = -1; for(i = 0; i < NTCB; i+)if(tcbi.state = FINISHED)id = i;break; if(id = -1)return -1

23、;disable(); tcbid.stack = (unsigned char *)malloc(stck);r = (struct int_regs *)(tcbid.stack + stck);r-;tcbid.ss=FP_SEG(r);tcbid.sp=FP_OFF(r);r->cs = FP_SEG(code);r->ip = FP_OFF(code);r->es = _DS;r->ds = _DS;r->flags = 0x200;r->seg = FP_SEG(over);r->of

24、f = FP_OFF(over);tcbid.state = READY;strcpy(, name);enable(); void interrupt swtch()int loop = 0;disable(); tcbcurrent.ss = _SS;tcbcurrent.sp = _SP; if(tcbcurrent.state = RUNNING)tcbcurrent.state = READY; while(tcb+current.state != READY && loop+ < NTCB - 1) if(curre

25、nt = NTCB)current = 0; if(tcbcurrent.state != READY)current = 0;_SS = tcbcurrent.ss;_SP = tcbcurrent.sp; tcbcurrent.state = RUNNING; timecount = 0; enable(); void destroy(int id)disable();free(tcbid.stack);tcbid.stack = NULL;tcbid.state = FINISHED;printf("nProcess %s terminatedn",

26、); 0 = 0;enable(); void over()destroy(current);swtch(); int finished()int i;for(i = 1; i < NTCB; i+)if(tcbi.state != FINISHED)return 0;return 1; void free_all(void)int i; for(i=NTCB;i>=0;i-)if(tcbi.stack)0=0;tcbi.state=FINISHED;free(tcbi.stack);tcbi.stack=N

27、ULL; void interrupt new_int8()(*old_int8)();timecount+;if(timecount < TL) return ;if(DosBusy()return ;swtch(); void wait(semaphore *sem) struct TCB *qp; disable();sem->value-;if(sem->value < 0) qp = &(sem->wq); block(qp); enable(); void signal(semaphore *se

28、m) struct TCB *qp; disable();qp = &(sem->wq); sem->value+;if(sem->value <= 0) wakeupFirst(qp); enable(); void block(struct TCB *qp) int id;struct TCB *tcbtmp;id = current;tcbid.state = BLOCKED;if(*qp) = NULL) (*qp) = &tcbid; elsetcbtmp = *qp;while(tcbtmp-&

29、amp;gt;next != NULL) tcbtmp = tcbtmp->next; tcbtmp->next = &tcbid; tcbid.next = NULL;swtch(); void wakeupFirst(struct TCB *qp)struct TCB *tcbtmp; if(*qp) = NULL)return ; tcbtmp = *qp;*qp = (*qp)->next;tcbtmp->state = READY;tcbtmp->next = NULL; void initBuf(

30、)int i;for(i = 0; i < NBUF - 1; i+)bufi.next = &bufi+1;bufi.next = NULL;freebuf = &buf0; struct buffer *getbuf()struct buffer *buff;buff = freebuf;freebuf = freebuf->next;return buff; void insert(struct buffer *mq, struct buffer *buff) struct buffer *temp;if(buff = NULL

31、)return ;buff->next = NULL;if(*mq = NULL)*mq = buff;elsetemp = *mq;while(temp->next != NULL) temp = temp->next;temp->next = buff; void send(char *receiver, char *a, int size) struct buffer *buff;int i, id = -1; disable();for(i = 0; i < NTCB; i+)if(strcmp(receiver,

32、) = 0) id = i;break;if(id = -1)printf("Error: Receiver not exist.n"); enable();return ;wait(&sfb);wait(&mutexfb);buff = getbuf();signal(&mutexfb); buff->id = current;buff->size = size;buff->next = NULL;strcpy(buff->text,

33、a); wait(&tcbid.mutex);insert(&tcbid.mq, buff);signal(&tcbid.mutex); signal(&tcbid.sm);enable(); struct buffer *remov(struct buffer *mq, int sender) struct buffer *buff, *p, *q;q = NULL;p = *mq;while(p->next != NULL) && (p->id != sender)

34、q = p;p = p->next;if(p->id = sender)buff = p;if(q = NULL)*mq = buff->next;elseq->next = buff->next;buff->next = NULL;return buff;elsereturn NULL; int receive(char *sender, char *b)int i, id = -1;struct buffer *buff;disable();for(i = 0; i < NBUF; i+)if

35、(strcmp(sender, ) = 0) id = i;break;if(id = -1)enable();return -1;wait(&tcbcurrent.sm);wait(&tcbcurrent.mutex);buff = remov(&(tcbcurrent.mq), id);signal(&tcbcurrent.mutex);if(buff = NULL)signal(&tcbcurrent.sm);enable();return -1;strcpy(b, buff-&gt

36、;text);wait(&mutexfb);insert(&freebuf, buff);signal(&mutexfb);signal(&sfb); enable(); return buff->size; void main()int select = -1; InitDos();initTCB(); old_int8 = getvect(8);strcpy(, "main");tcb0.state = RUNNING;current = 0; while(s

37、elect != 0)doclrscr();printf("0. Exitn");printf("1. First come first serven");printf("2. Time slicen");printf("3. Change TL, see what would changen"); printf("4. Exclusively assessn");printf("5. Produc

38、er and consumer problemn"); printf("6. Message buffer communicationn"); scanf("%d", &select);while(select < 0 | select > 7); switch(select)case 1:create("f1", (codeptr)f1, NSTACK); create("f2", (co

39、deptr)f2, NSTACK); clrscr();printf("ncreate f1 and f2n"); printf("f1 prints 10 an"); printf("f2 prints 8 bn"); swtch();getch();break;case 2:TL = 1;printf("Time slice = 1nn"); getch();create("f1", (codeptr)f1, N

40、STACK); create("f2", (codeptr)f2, NSTACK); create("f3", (codeptr)f3, NSTACK); clrscr();printf("ncreate f1, f2, f3n"); printf("f1 prints 10 an"); printf("f2 prints 8 bn"); printf("f3 prints 6 cn&quo

41、t;); setvect(8, new_int8);swtch();getch();break;case 3:printf("Enter new time slice: "); scanf("%d", &TL);printf("Time slice = %dnn", TL); getch();create("f1", (codeptr)f1, NSTACK); create("f2", (codeptr)f2, NSTACK); create("f3", (codeptr)f3, NSTACK); clrscr();printf("ncreate f1, f2, f3n"); printf("f1 prints 10 an"); printf("f2 prints 8 bn"); printf("f3 prints 6 cn&a

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论