操作系统.docx
《操作系统.docx》由会员分享,可在线阅读,更多相关《操作系统.docx(17页珍藏版)》请在冰豆网上搜索。
操作系统
课程设计(论文)任务书
软件 学 院 软件测试 专 业 06级
(2)班
一、课程设计(论文)题目 读者写者问题
二、课程设计(论文)工作自2009年1月5日起至2009年1月9日止。
三、课程设计(论文)地点:
教5–信息学院机房
四、课程设计(论文)内容要求:
1.课程设计的目的
(1)通过课程设计,使学生对整个课程的知识体系有较深入的理解;
(2)通过模拟操作系统原理的实现,使学生能更深刻地领会操作系统工作原理和
理解操作系统的实现方法;
(3)利用本课程内的以及到目前为止所学到的有关知识和技术解决一些不太复
杂的问题,提高学生的实践动手能力;
(4)提高学生的科技论文写作能力。
2.课程设计的任务及要求
1)基本要求
(1)课程设计前必须根据课程设计题目认真准备实验程序及调试时所需的输入数据;
(2)要求采用简明、严格的问题描述,设计求解算法;
(3)数据结构选用得当,实现算法,程序结构合理;
(4)程序简明易懂,多运用输入输出提示,多对程序进行测试,发现错误和缺陷;
(5)对设计进行总结和讨论。
2)课程设计论文编写要求
(1)要按照书稿的规格撰写打印课设论文
(2)论文包括中文摘要、目录、绪论、正文、小结、参考文献、附录等
(3)正文中要有问题描述、设计求解算法、算法的实现、调试、总结和讨论
(4)课设论文装订按学校的统一要求完成
3)课设考核
从以下几方面来考查:
(1)出勤情况;
(2)设计任务的难易程度及饱满程度;
(3)课设任务完成情况;
(4)动手调试能力;
(5)论文撰写的原理分析、设计思路以及论述的层次性、条理性、格式的规范性。
4)参考文献
[1]计算机操作系统.西安电子科技大学出版社
[2]C++Primet.人民邮电出版社
[3]http:
5)课程设计进度安排
内容天数 地点
构思及收集资料1 图书馆
程序设计与调试3 计算机房
撰写论文1 图书馆
6)任务及具体要求
创建一个控制台进程,此进程包含n个线程。
用这n个线程来表示n个读者或写者。
每个线程按相应测试数据文件的要求进行读写操作。
用信号量机制分别实现读者优先
和写者优先问题。
运行结果显示要求:
要求在每个线程创建、发出读写申请、开始读
写操作和结束读写操作时分别显示一行提示信息,以确定所有处理都遵守相应的读写
操作限制。
学生签名:
2009年1月5日
课程设计(论文)评审意见
(1)任务难易及完成情况:
优( )、良( )、中( )、一般( )、差( );
(2)完成调试能力评价 :
优( )、良( )、中( )、一般( )、差( );
(3)论文撰写水平评价 :
优( )、良( )、中( )、一般( )、差( );
(4)论文格式规范性评价:
优( )、良( )、中( )、一般( )、差( );
(5)考勤:
优( )、良( )、中( )、一般( )、差( );
评阅人:
职称:
讲师
2009年1月12日
摘要
相关WindowsAPI说明:
1.CreateThread:
创建一个在调用进程的地址空间中执行的线程。
2.ExitThread
3.Sleep:
对指定的时间间隔挂起当前的执行线程
4.CreateMutex:
创建有名或者无名的互斥对象
5.ReleaseMutex:
6.WaitForSingleObject:
当发生
(1)指定对象处于信号态
(2)超时则该函数返回
7.WaitForMultipleObject:
任意一个或全部指定对象处于信号态或超时间隔已过时,返回
8.CreateSemapore:
创建一个有名或无名信号对象。
9.ReleaseSemapore:
10.InitializeCriticalSection:
初始化临界区对象
11.EnterCriticalSection:
等待指定临界区对象的所有权。
当调用线程被赋予所有权时,返回。
12.LeaveCriticalSection:
该函数释放指定临界区对象的所有权。
目 录
摘要1
1绪论3
1.1设计题目及要求3
1.1.1设计题目3
1.1.2设计要求3
2实验内容4
2.1.1整体概括4
2.1.2读者优先4
2.1.3写者优先4
3概要设计5
3.1.1整体流程图5
3.1.2读者优先7
3.1.3写者优先8
4详细设计9
5测试结果15
6小结17
参考文献18
1绪论
操作系统(OS)是最重要的计算机系统软件。
同时也是最活跃的学科之一。
操作系统(OS)是配置在计算机硬件上的第一层软件,是对硬件系统的首次扩充。
它在计算机系统中占了重要的地位。
大量的应用软件,都将依赖于操作系统的支持,取的它的服务。
1.1设计题目及要求
1.1.1设计题目
读者写者问题是一个经典的进程同步问题。
所涉及的算法虽然不是很难,但是也要去花一些功夫的.我们一般把只要求读该文件的进程称为”Reader进程”,其他进程则称为”Writer进程”.允许多个进程同时读一个共享对象.但不允许一个Writr进程和其他Reader进程同时访问共享对象.读者写者问题是指保证一个Writer进程必须与其他进程互斥地访问共享对象的同步问题.
1.1.2设计要求
读者-写者问题的读写操作限制(包括读者优先和写者优先)
1.写-写互斥:
不能有两个写者同时进行写操作
2.读-写互斥:
不能同时有一个线程在读,而另一个线程在写。
3.读-读允许:
可以有一个或多个读者在读。
若读者的优先权比写者高,如果读者申请进行读操作时已有另一个读者正在进行读操作,则该读者可直接开始读操作.不必经过别的操件
若读者的优先权比写者高,如果第一个写者已经占有了文件的时候.则别的读者必需等待该操作完成后.才能开始读操作.
若写者的优先权比读者高,在一个写者提出要访问文件时,就必须使其尽可能的得到文件,而且不用调配。
2实验内容
2.1.1整体概括
该程序从大体上来分只有两个模块,即”读者优先”和”写者优先”模块.
2.1.2读者优先
:
如果没有写者正在操作,则读者不需要等待,用一个整型变量readcount记录读者数目,用于确定是否释放读者线程,readcount的初值为0.当线程开始调入时.每个读者准备读.等待互斥信号,保证对readcount的访问,修改互斥.即readcount++.而当读者线程进行读操作时,则读者数目减少(readcount--).当readcout=0时,说明所有的读者都已经读完,离开临界区唤醒写者(LeaveCriticalSection(&RP_Write);),释放互斥信号(ReleaseMutex(h_Mutex)).
还需要一个互斥对象mutex来实现对全局变量Read_count修改时的互斥.另外,为了实现写-写互斥,需要增加一个临界区对象Write。
当写者发出写请求时,必须申请临界区对象的所有权。
通过这种方法,可以实现读-写互斥,当Read_count=1时(即第一个读者到来时),读者线程也必须申请临界区对象的所有权
2.1.3写者优先
写者优先与读者不同之处在于一旦一个写者到来,它应该尽快对文件进行写操作,如果有一个写者在等待,则新到来的读者不允许进行读操作。
为此应当填加一个整形变量write_count,用于记录正在等待的写者的数目,write_count的初值为0.当线程开始调入时.只允许一个写者准备读.等待互斥信号,保证对write_count的访问,修改互斥.即write_count++.而当写者线程进行读操作时,则相应写者数目减少(write_count--).当write_count=0时,说明所有的读者都已经读完,离开临界区唤醒读者,释放互斥信号.
为了实现写者优先,应当填加一个临界区对象read,当有写者在写文件或等待时,读者必须阻塞在read上。
3概要设计
3.1.2整体流程图
3.1.2读者优先
3.1.3写者优先
4详细设计
1.主函数
intmain(intargc,char*argv[])
{
charch;
while(true)
{
printf("选择读者优先请按“1”\n");
printf("选择写者优先请按“2”\n");
printf("选择退出请按“3”\n\n\n");
printf("请选择(1,2,3):
\n");
do{
ch=(char)_getch();
}while(ch!
='1'&&ch!
='2'&&ch!
='3');
system("cls");
if(ch=='3')
return0;
elseif(ch=='1')
ReaderPriority("thread.dat");
else
WriterPriority("thread.dat");
printf("\nPressAnyKeytoCoutinue:
");
_getch();
system("cls");
}
return0;
}
2.读者优先---读者线程
读者线程信息关键代码
等待互斥信号,保证对ReadCount的访问,修改互斥
wait_for_mutex=WaitForSingleObject(h_Mutex,-1);
//读者数目增加
readcount++;
if(readcount==1)
{
EnterCriticalSection(&RP_Write);
}
ReleaseMutex(h_Mutex);//
printf("线程%d开始读......\n",m_serial);
Sleep(m_persist);
printf("线程%d读完毕。
\n",m_serial);
//等待互斥信号,保证对ReadCount的访问,修改互斥
wait_for_mutex=WaitForSingleObject(h_Mutex,-1);
//读者数目减少
readcount--;
if(readcount==0)
{
//如果所有的读者读完,唤醒写者
LeaveCriticalSection(&RP_Write);
}
3.写者线程信息关键代码
printf("线程%d开始写......\n",m_serial);
Sleep(m_persist);
printf("线程%d写完毕。
\n",m_serial);
LeaveCriticalSection(&RP_Write);
读者优先处理函数关键代码
voidReaderPriority(char*file)
//互斥对象
HANDLEh_Mutex;
h_Mutex=CreateMutex(NULL,FALSE,"mutex_for_readcount");
//线程对象的数组
HANDLEh_Thread[MAX_THREAD_NUM];
ThreadInfothread_info[MAX_THREAD_NUM];
for(inti=0;i<(int)(n_thread);i++)
{
if(thread_info[i].entity==READER||thread_info[i].entity=='r')
{
//创建读者进程
h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(RP_ReaderThread),&thread_info[i],0,&thread_ID);
}
else
{
//创建写线程
h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(RP_WriterThread),&thread_info[i],0,&thread_ID);
写者优先---读者线程
voidWP_ReaderThread(void*p)
{
printf("第%d线程准备读。
\n",m_serial);
wait_for_mutex1=WaitForSingleObject(h_Mutex1,-1);
//读者进去临界区
EnterCriticalSection(&cs_Read);
//阻塞互斥对象Mutex2,保证对readCount的访问和修改互斥
wait_for_mutex2=WaitForSingleObject(h_Mutex2,-1);
//修改读者的数目
readcount++;
if(readcount==1)
{
//如果是第1个读者,等待写者写完
EnterCriticalSection(&cs_Write);
}
ReleaseMutex(h_Mutex2);//释放互斥信号Mutex2
//让其他读者进去临界区
LeaveCriticalSection(&cs_Read);
ReleaseMutex(h_Mutex1);
//退出线程
printf("线程%d读完毕。
\n",m_serial);
//阻塞互斥对象Mutex2,保证对readcount的访问,修改互斥
wait_for_mutex2=WaitForSingleObject(h_Mutex2,-1);
readcount--;
if(readcount==0)
{
//最后一个读者,唤醒写者
LeaveCriticalSection(&cs_Write);
}
ReleaseMutex(h_Mutex2);//释放互斥信号
}
写者线程信息关键代码
wait_for_mutex3=WaitForSingleObject(h_Mutex3,-1);
writecount++;//修改写者数目
if(writecount==1)
{
EnterCriticalSection(&cs_Read);
}
printf("线程%d开始写......\n",m_serial);
Sleep(m_persist);
printf("线程%d写完毕。
\n",m_serial);
LeaveCriticalSection(&cs_Write);
wait_for_mutex3=WaitForSingleObject(h_Mutex3,-1);
writecount--;
if(writecount==0);
LeaveCriticalSection(&cs_Read);
5测试结果
测试数据文件
1r24
2w33
3r55
4w44
5r51
6r64
当所测试的线程多时,就有可能导致每次测试时一些线程的运行顺序不一样。
以下两图就是“读者优先”和“写者优先”都经过三次测试。
但线程的顺序都不一样的结果。
6小结
经过此次数据库课程设计的煅练感觉受益非浅。
学到许多在课程里没有学会的东西。
这次作业耗费的时间还是蛮多的,主要不是设计方案问题,而是一些细节上问题很多,比如一开始的时候对共享内存的使用不是很了解,进行了多次实验,然后是信号量上的一个问题困扰了我很久,就是PV操作的置位问题。
一开始参考其他资料将其置在别的位置,孰不知此置位方式在某个子进程结束时,相应的操作将被取消。
这样会导致其他子进程被阻塞。
设置此标志位是为了防止进程在没有释放共享资源就退出时,内核将代为释放,后来将它改为0,程序就正确了.还有是在中断读者线程问题上了了点问题,后来经过设置了readcount变量成功的解决了这个问题
参考文献
计算机操作系统.西安电子科技大学出版社
C++Primer.人民邮电出版社
http: