操作系统课程设计实验报告短学期.docx
- 文档编号:6411019
- 上传时间:2023-01-06
- 格式:DOCX
- 页数:30
- 大小:66.63KB
操作系统课程设计实验报告短学期.docx
《操作系统课程设计实验报告短学期.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计实验报告短学期.docx(30页珍藏版)》请在冰豆网上搜索。
操作系统课程设计实验报告短学期
操作系统课程设计
实验报告
姓名:
董永文
专业:
软件工程
班级:
07052714
学号:
07057409
2010年7月
任务一、基于线程的多任务程序设计
一、实验目的
本实验旨在促进对于线程控制、调度算法和消息通信机制的理解。
这里的多线程并不使用任何的操作系统提供的线程系统调用,而是依靠自己的线程相关函数完成上述目标,线程的调度依靠的是改造后的时钟中断处理程序来实现的。
二、实验要求
本实验要求实现如下要求:
1.设计实现基于线程多任务程序
2.完成生产者消费者程序设计
3.实现线程间的消息通信程序
三、已经实现的功能
1.设计实现基于线程多任务程序
2.完成生产者消费者程序设计
3.实现线程间的消息通信程序
四、未能实现的功能
五、程序设计思路与代码分析
任务一主要需要实现的功能可以分为五部分:
(一)线程的创建和撤消
(二)调度程序的实现
(三)进程的阻塞和唤醒
(四)利用消息缓冲队列的线程间通信
(五)生产者消费者问题的实现
因此本程序可以以上功能实现先后顺序为设计思路,进行代码编写。
(一)线程的创建和撤消
1、TCB的设计:
TCB是实现以上功能的必要前提,所以要考虑周全
#defineFINISHED 0
#defineRUNNING 1
#defineREADY 2
#defineBLOCKED 3
#defineNTCB 100
structTCB
{
unsignedchar *stack; /*堆栈的起始地址*/
unsigned ss; /*堆栈段址*/
unsigned sp; /*堆栈指针*/
char state; /*线程的外部标识符*/
char name[10];/*NTCB是系统允许的最多任务个数*/
structbuffer*mq;/*消息队列队首指针,初值为NULL*/
structsemaphoremutex; /*消息队列的互拆信号量,初值为{1,NULL}*/
structsemaphoresm; /*消息队列的计数信号量,初值为{0,NULL}*/
intreaderNum;/*当线程作为读线程时所读线程的线程内部标识符*/
}tcb[NTCB];
2、创建线程:
线程创建的一般步骤
1.为新线程分配一个线程控制块,TCB数组的下标即为该线程的内部标识符。
2.为新线程分配私有堆栈空间。
3.初始化新线程的私有堆栈,即按CPU调度时现场信息的保存格式布置堆栈。
4.初始化线程控制块。
5.其它工作。
如按优先级进行CPU调度,则需在TCB中加上优先权信息。
6.返回新线程的内部标识符。
为新线程分配私有堆栈空间
intcreate(char*name,codeptrcode,unsignedstacklen,unsignedprio)
{
inti;
structint_regs*ir;
for(i=1;i if(tcb[i].state==FINISHED) break; if(i==NTCB)return-1; strcpy(tcb[i].name,name); tcb[i].stack=(unsignedchar*)malloc(stacklen); tcb[i].ss=FP_SEG(tcb[i].stack); tcb[i].sp=FP_OFF(tcb[i].stack+stacklen); tcb[i].state=READY; tcb[i].prio=prio; *((unsigned*)(tcb[i].sp-2))=FP_SEG(over); *((unsigned*)(tcb[i].sp-4))=FP_OFF(over); tcb[i].sp-=(sizeof(structint_regs)+4); ir=(structint_regs*)tcb[i].sp; ir->ds=tcb[i].ss; ir->es=tcb[i].ss; ir->ip=FP_OFF(code); ir->cs=FP_SEG(code); ir->flags=0x200; returni; } 3、撤消线程 1.释放线程的私有堆栈空间。 2.重新进行CPU调度。 voidover() { if(tcb[current].state==RUNNING) { free(tcb[current].stack); tcb[current].state=FINISHED; } SWITCH(); /*重新进行CPU调度*/ } (二)调度程序的实现 利用时钟中断来进行CPU调度,设计中要注意: 新中断处理程序不能太长,否则系统效率将大大降低甚至使系统无法正常工作;在新的时钟中断处理程序里必须调用系统原来的INT08H,否则将影响磁盘马达和系统的计时。 voidinterruptSWITCH() { disable(); tcb[current].ss=_SS; tcb[current].sp=_SP; if(tcb[current].state==RUNNING) tcb[current].state=READY; current=find(); _SS=tcb[current].ss; _SP=tcb[current].sp; tcb[current].state=RUNNING; enable(); } voidinterruptnew_int8() { /*调用原来的中断处理程序*/ (*old_int8)(); timecount++; /*优先级加1*/ tcb[current].prio++; if(timecount>=TLE) { disable(); tcb[current].ss=_SS; tcb[current].sp=_SP; if(tcb[current].state==RUNNING) tcb[current].state=READY; current=find(); _SS=tcb[current].ss; _SP=tcb[current].sp; tcb[current].state=RUNNING; timecount=0; enable(); } } (三)进程的阻塞和唤醒 线程阻塞过程: 将线程的状态改成阻塞态,将线程插入指定的阻塞队列末尾,并重新进行CPU调度。 线程唤醒过程: 把阻塞队列头上的第一个线程的TCB取下来,并将其状态改为就绪态,并重新进行CPU调度。 structblock_entry {unsigned thread; structblock_entry*next;}; structsemaphore { int value; structblock_entry*L;}; voidInitSemaphore(structsemaphore*ps) { ps->value=SIGNAL_VALUE; ps->L =NULL;} voidblock(structsemaphore*ps) { structblock_entry*pbe; tcb[current].state=BLOCKED; pbe=(structblock_entry*)malloc(sizeof(structblock_entry)); pbe->thread=current; pbe->next =ps->L; ps->L =pbe; printf("Thread%disblocked! \n",current); SWITCH(); } voidwakeup(structsemaphore*ps) { structblock_entry*pbe; pbe=ps->L; if(! pbe) { printf("Blockqueueisempty! \n"); SWITCH(); } tcb[pbe->thread].state=READY; ps->L=pbe->next; free(pbe); printf("Thread%dhasbeenwakedup! \n",pbe->thread); SWITCH(); } voidwait(structsemaphore*ps) { disable(); ps->value--; if(ps->value<0) block(ps); enable();} voidsignal(structsemaphore*ps) { disable(); ps->value++; if(ps->value<=0) wakeup(ps); enable();} (四)利用消息缓冲队列的线程间通信 假设刚开始时系统中有NBUF个消息缓冲区,它们排成一个消息队列freebuf,为实现对该队列操作的互斥,设置信号量mutexb(初值 为{1,NULL})。 发送消息时,发送者必须提供接收者的标识符、消息的长度及消息正文的起始地址等信息。 接收消息时,接收者必须指出发送者的标识符、接收区的起始地址等信息。 /*从空闲消息缓冲队列头上取下一缓冲区,返回指向该缓冲区的指针*/ structbuffer*getbuf() { structbuffer*buff; buff=freebuf; freebuf=freebuf->next; returnbuff; } /*将buff所指向的消息缓冲区加到空闲消息缓冲队列中去*/ voiddropbuf(structbuffer*buff) { buff->next=freebuf; freebuf=buff; } /*将buff所指的缓冲区插到*mq所指的缓冲队列末尾*/ voidinsert(structbuffer**mq,structbuffer*buff) { structbuffer*temp; if(buff==NULL)return; buff->next=NULL; if(*mq==NULL) *mq=buff; else { temp=*mq; while(temp->next) temp=temp->next; temp->next=buff; } } /*从*mq所指的缓冲队列中移除buff所指的缓冲区*/ voiddelet(structbuffer**mq,structbuffer*buff) { structbuffer*temp; if(! *mq)return; if(! buff)return; if(*mq==buff) { *mq=buff->next; return; } for(temp=*mq;temp->next! =buff;temp=temp->next); temp->next=buff->next; } /*将地址a开始的size个字节内容发送给receiver线程*/ voidsend(char*receiver,char*a,intsize) { structbuffer*buff; inti,id=-1; disable(); for(i=0;i if(! strcmp(receiver,tcb[i].name)) { id=i; break; } if(-1==id) { printf("Error: Receivernotexsist! \n"); enable(); return; } wait(&sfb); wait(&mutexfb); buff=getbuf(); signal(&mutexfb); buff->sender=current; buff->size=size; buff->next=NULL; for(i=0;i buff->text[i]=*a; wait(&tcb[id].mutex); insert(&(tcb[id].mq),buff); signal(&tcb[id].mutex); signal(&tcb[id].sm); enable(); } /*接收sender发送来的消息到a所指的缓冲区中*/ voidrecv(char*sender,char*a) { structbuffer*buff; inti,id=-1; buff=tcb[current].mq; disable(); while(buff) { /*printf("%d\n",buff->sender);*/ if(! strcmp(sender,tcb[buff->sender].name)) { id=buff->sender; break; } buff=buff->next; } if(-1==id) { printf("Error: Sendernotexsist! \n"); enable(); return; } for(i=0;i *a=buff->text[i]; wait(&tcb[current].mutex); delet(&(tcb[current].mq),buff); signal(&tcb[current].mutex); wait(&tcb[current].sm); signal(&sfb); wait(&mutexfb); dropbuf(buff); signal(&mutexfb); enable(); } (五)生产者消费者问题的实现 voidproduce() { inti; for(i=0;i<10;i++){ disable(); production=rand()%(Y-X+1)+X; production*=production; fprintf(fp,"current=%dprodece1produce_cnt=%dconsume_cnt=%dproduction=%d\n",current,produce_cnt,consume_cnt,production); enable(); wait(empty); wait(mutex); produce_cnt++; disable(); fprintf(fp,"current=%dprodece2produce_cnt=%dconsume_cnt=%dproduction=%d\n",current,produce_cnt,consume_cnt,production); enable(); signal(mutex); signal(full); } } voidconsume() { inti; for(i=0;i<10;i++){ disable(); fprintf(fp,"current=%dconsume1produce_cnt=%dconsume_cnt=%dproduction=%d\n",current,produce_cnt,consume_cnt,production); enable(); wait(full); wait(mutex); consume_cnt++; disable(); fprintf(fp,"current=%dconsume2produce_cnt=%dconsume_cnt=%dproduction=%d\n",current,produce_cnt,consume_cnt,production); enable(); signal(mutex); signal(empty); } } 六、实验结论 1、线程间通信的结果如下: Thread1: Sendthread2: thread1tothread2-1! Thread2: Sendthread3: thread2tothread3-1! Thread3: Sendthread1: thread3tothread1-1! Thread1: Sendthread2: thread1tothread2-2! Thread2: Sendthread3: thread2tothread3-2! Thread3: Sendthread1: thread3tothread1-2! Thread1: Sendthread2: thread1tothread2-3! Thread2: Sendthread3: thread2tothread3-3! Thread3: Sendthread1: thread3tothread1-3! Thread1: Sendthread2: thread1tothread2-4! Thread2: Sendthread3: thread2tothread3-4! Thread3: Sendthread1: thread3tothread1-4! Thread1: Sendthread2: thread1tothread2-5! Thread2: Sendthread3: thread2tothread3-5! Thread3: Sendthread1: thread3tothread1-5! Thread1: Recvivemessage: thread3tothread1-1! Thread2: Recvivemessage: thread1tothread2-1! Thread3: Recvivemessage: thread2tothread3-1! Thread1: Recvivemessage: thread3tothread1-2! Thread2: Recvivemessage: thread1tothread2-2! Thread3: Recvivemessage: thread2tothread3-2! Thread1: Recvivemessage: thread3tothread1-3! Thread2: Recvivemessage: thread1tothread2-3! Thread3: Recvivemessage: thread2tothread3-3! Thread1: Recvivemessage: thread3tothread1-4! Thread2: Recvivemessage: thread1tothread2-4! Thread3: Recvivemessage: thread2tothread3-4! Thread1: Recvivemessage: thread3tothread1-5! Thread2: Recvivemessage: thread1tothread2-5! Thread3: Recvivemessage: thread2tothread3-5! ============Thread1isover! ============Thread2isover! ============Thread3isover! 2、生产者消费者问题的实现结果如下: current=1prodece1produce_cnt=0consume_cnt=0production=2209 current=1prodece2produce_cnt=1consume_cnt=0production=2209 current=1prodece1produce_cnt=1consume_cnt=0production=961 current=1prodece2produce_cnt=2consume_cnt=0production=961 current=1prodece1produce_cnt=2consume_cnt=0production=1089 current=1prodece2produce_cnt=3consume_cnt=0production=1089 current=1prodece1produce_cnt=3consume_cnt=0production=1681 current=1prodece2produce_cnt=4consume_cnt=0production=1681 current=1prodece1produce_cnt=4consume_cnt=0production=49 current=1prodece2produce_cnt=5consume_cnt=0production=49 current=1prodece1produce_cnt=5consume_cnt=0production=324 Thread1isblocked! current=2consume1produce_cnt=5consume_cnt=0production=324
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 课程设计 实验 报告 学期