2022年《操作系统》课程设计报告 .pdf
《2022年《操作系统》课程设计报告 .pdf》由会员分享,可在线阅读,更多相关《2022年《操作系统》课程设计报告 .pdf(19页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、操作系统课程设计报告一、读者 /写者的问题模拟实现读者 /写者问题, 是指保证一个writer 进程必须与其他进程互斥地访问共享对象的同步问题。读者写者问题可以这样的描述:有一群写者和一群读者,写者在写同一本书,读者也在读这本书, 多个读者可以同时读这本书,但是只能有一个写者在写书,并且读者必优先,也就是说, 读者和写者同时提出请求时,读者优先。当读者提出请求时,需要有一个互斥操作,另外需要有一个信号量S 来确定当前是否可操作。信号量机制是支持多道程序的并发操作系统设计中解决资源共享时进程间的同步与互斥的重要机制,而读者写者则是这一机制的一个经典范例。与记录型信号量解决读者写者问题不同,信号量
2、机制它增加了一个限制,即最多允许RN 个读者同时读。为此,又引入了一个信号量L,并赋予初值为RN,通过执行wait (L,1,1)操作来控制读者的数目,每当有一个读者进入时,就要执行wait(L,1,1)操作,使L 的值减1。当有RN 个读者进入读后,L 便减为0,第RN+1 个读者要进入读时,必然会因wait(L,1,1 )操作失败而堵塞。程序实例:#include #include #include #include #include #include #define MAX_PERSON 100 #define READER 0 /读者#define WRITER 1 /写者#defin
3、e END -1 #define R READER #define W WRITER typedef struct _Person HANDLE m_hThread;/ 定义处理线程的句柄int m_nType;/进程类型(读写)int m_nStartTime;/ 开始时间int m_nWorkTime;/ 运行时间int m_nID;/ 进程号Person; Person g_PersonsMAX_PERSON; int g_NumPerson = 0; long g_CurrentTime= 0;/ 基本时间片数int g_PersonLists = / 进程队列1, W, 3, 5,
4、2, W, 16, 5, 3, R, 5, 2, 4, W, 6, 5, 5, R, 4, 3, 6, R, 17,7, 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 19 页 - - - - - - - - - END, ; int g_NumOfReading = 0; int g_NumOfWriteRequest = 0;/ 申请写进程的个数HANDLE g_hReadSemaphore;/ 读者信号HANDLE g_hWriteSemaphore;/ 写者信号
5、bool finished = false; / 所有的读完成/bool wfinished = false; / 所有的写完成void CreatePersonList(int *pPersonList); bool CreateReader(int StartTime,int WorkTime,int ID); bool CreateWriter(int StartTime,int WorkTime,int ID); DWORD WINAPI ReaderProc(LPVOID lpParam); DWORD WINAPI WriterProc(LPVOID lpParam); int m
6、ain() g_hReadSemaphore = CreateSemaphore(NULL,1,100,NULL); /创建信号灯, 当前可用的资源数为 1,最大为100 g_hWriteSemaphore = CreateSemaphore(NULL,1,100,NULL); /创建信号灯,当前可用的资源数为 1,最大为100 CreatePersonList(g_PersonLists); / Create All the reader and writers printf(Created all the reader and writern 创建 n); g_CurrentTime =
7、0; while(true) g_CurrentTime+; Sleep(300); / 300 ms printf(CurrentTime = %dn,g_CurrentTime); if(finished) return 0; / return 0; void CreatePersonList(int *pPersonLists) int i=0; int *pList = pPersonLists; bool Ret; while(pList0 != END) switch(pList1) case R: Ret = CreateReader(pList2,pList3,pList0);
8、/351,w452,523,654 break; case W: Ret = CreateWriter(pList2,pList3,pList0); break; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 19 页 - - - - - - - - - if(!Ret) printf(Create Person %d is wrongn,pList0); pList += 4; / move to next person list DWORD WINAPI Reade
9、rProc(LPVOID lpParam)/读过程 Person *pPerson = (Person*)lpParam; / wait for the start time while(g_CurrentTime != pPerson-m_nStartTime) printf(Reader %d is Requesting 等待 n,pPerson-m_nID); printf(nn*n); / wait for the write request WaitForSingleObject(g_hReadSemaphore,INFINITE); if(g_NumOfReading =0) Wa
10、itForSingleObject(g_hWriteSemaphore,INFINITE); g_NumOfReading+; ReleaseSemaphore(g_hReadSemaphore,1,NULL); pPerson-m_nStartTime = g_CurrentTime; printf(Reader %d is Reading the Shared Buffer等待 n,pPerson-m_nID); printf(nn*n); while(g_CurrentTime m_nStartTime + pPerson-m_nWorkTime) printf(Reader %d is
11、 Exit退出 n,pPerson-m_nID); printf(nn*n); WaitForSingleObject(g_hReadSemaphore,INFINITE); g_NumOfReading-; if(g_NumOfReading = 0) ReleaseSemaphore(g_hWriteSemaphore,1,NULL);/ 此时没有读者,可以写 ReleaseSemaphore(g_hReadSemaphore,1,NULL); if(pPerson-m_nID = 4) finished = true; /所有的读写完成ExitThread(0); return 0; D
12、WORD WINAPI WriterProc(LPVOID lpParam) Person *pPerson = (Person*)lpParam; / wait for the start time while(g_CurrentTime != pPerson-m_nStartTime) printf(Writer %d is Requesting 请求进行写操作n,pPerson-m_nID); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 19 页 - - - -
13、 - - - - - printf(nn*n); WaitForSingleObject(g_hWriteSemaphore,INFINITE); / modify the writers real start time pPerson-m_nStartTime = g_CurrentTime; printf(Writer %d is Writting the Shared Buffer写内容 n,pPerson-m_nID); while(g_CurrentTime m_nStartTime + pPerson-m_nWorkTime) printf(Writer %d is Exit退出
14、n,pPerson-m_nID); printf(nn*n); /g_NumOfWriteRequest-; ReleaseSemaphore(g_hWriteSemaphore,1,NULL); if(pPerson-m_nID = 4) finished = true;/所有的读写完成ExitThread(0); return 0; bool CreateReader(int StartTime,int WorkTime,int ID) DWORD dwThreadID; if(g_NumPerson = MAX_PERSON) return false; Person *pPerson
15、= &g_Personsg_NumPerson; pPerson-m_nID = ID; pPerson-m_nStartTime = StartTime; pPerson-m_nWorkTime = WorkTime; pPerson-m_nType = READER; g_NumPerson+; / Create an New Thread pPerson-m_hThread= CreateThread(NULL,0,ReaderProc,(LPVOID)pPerson,0,&dwThreadID); if(pPerson-m_hThread = NULL) return false; r
16、eturn true; bool CreateWriter(int StartTime,int WorkTime,int ID) DWORD dwThreadID; if(g_NumPerson = MAX_PERSON) return false; Person *pPerson = &g_Personsg_NumPerson; pPerson-m_nID = ID; pPerson-m_nStartTime = StartTime; pPerson-m_nWorkTime = WorkTime; pPerson-m_nType = WRITER; g_NumPerson+; / Creat
17、e an New Thread 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 19 页 - - - - - - - - - pPerson-m_hThread= CreateThread(NULL,0,WriterProc,(LPVOID)pPerson,0,&dwThreadID); if(pPerson-m_hThread = NULL) return false; return true; 二、进程间通信与子进程使用管道进行父子进程间通信,程序首先判断参数是否合法
18、,因为输入的字符将从父进程通过发送到子进程中。然后调用pipe 函数创建父子进程用于通信的管道。使用fork 函数创建子进程时, 子进程会获得与父进程相同的资源,其中包括文件描述符信息。因此,调用fork 函数须在 pipe 函数调用前。 当父子进程通过管道进行通信时,files1 为用于数据写入的文件描述符 .因此 ,在子进程中 ,要读取管道中的数据可以调用read函数,而读取得文件描述符为 files0 。对于父进程而言,写入数据需要调用write 函数,要写入的文件描述为files1 。程序代码:#include #include int main(int argc,char* argv
19、) int f_des2; int pid; char msgBUFSIZ; if(argc!=2) printf(Usage: %s messagen,argv0); return 1; if(pipe(f_des)=-1) perror(cannot create the IPC pipe); return 1; pid=fork(); if(pid=-1) perror(cannot create new process); return 1; else if(pid=0) close(f_des1); if(read(f_des0,msg,BUFSIZ)=-1) perror(chil
20、d process cannot read data from pipe); return 1; else printf(in child process, receive message: %sn,msg); _exit(0); else close(f_des0); if(write(f_des1,argv1,strlen(argv1)=-1) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 19 页 - - - - - - - - - perror(parent p
21、rocess cannot write data to pipe); return 1; else printf(in parent process, send message: %sn,argv1); wait(NULL); _exit(0); return 0; 三、进程多级调度模拟1.设置多个就绪队列,并给队列赋予不同的优先级数,第一个最高,依次递减。2.赋予各个队列中进程执行时间片的大小,优先级越高的队列,时间片越小。3.当一个新进程进入内存后,首先将其放入一个对列末尾,如果在一个时间片结束时尚未完成,将其转入第二队列末尾。4.当一个进程从一个对列移至第n 个队列后,便在第n 个队列中
22、采用时间片轮转执行完。5.仅当时间片空闲时,才调度第二个队列中的进程。(1i-1) 空闲时,才调度i,如果处理机正在第i 队列中运行,又有新进程进入优先权较高队列,则新进程抢占处理机,将正在运行的进程放入第i 队列队尾,将处理机分给新进程。程序代码:#include #include #include typedef struct node /* 进程节点信息*/ char name20; /* 进程的名字 */ int prio; /*进程的优先级*/ int round; /*分配 CPU 的时间片 */ int cputime; /*CPU 执行时间 */ int needtime; /
23、*进程执行所需要的时间*/ char state; /*进程的状态,W 就绪态, R 执行态, F 完成态 */ int count; /* 记录执行的次数*/ struct node *next; /*链表指针 */ PCB; typedef struct Queue /* 多级就绪队列节点信息*/ PCB *LinkPCB; /*就绪队列中的进程队列指针*/ int prio; /*本就绪队列的优先级*/ int round; /*本就绪队列所分配的时间片*/ struct Queue *next; /* 指向下一个就绪队列的链表指针*/ ReadyQueue; PCB *run=NULL
24、,*finish=NULL; /*定义三个队列,就绪队列,执行队列和完成队列*/ ReadyQueue *Head = NULL; /* 定义第一个就绪队列*/ 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 19 页 - - - - - - - - - int num; /*进程个数 */ int ReadyNum; /*就绪队列个数 */ void Output(); /*进程信息输出函数*/ void InsertFinish(PCB *in); /* 将进程插入到
25、完成队列尾部*/ void InsertPrio(ReadyQueue *in); /* 创建就绪队列,规定优先数越小,优先级越低*/ void PrioCreate(); /* 创建就绪队列输入函数*/ void GetFirst(ReadyQueue *queue); /*取得某一个就绪队列中的队头进程*/ void InsertLast(PCB *in,ReadyQueue *queue); /*将进程插入到就绪队列尾部*/ void ProcessCreate(); /*进程创建函数*/ void RoundRun(ReadyQueue *timechip); /* 时间片轮转调度算法
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 2022年操作系统课程设计报告 2022 课程设计 报告
限制150内