操作系统课程设计.docx

上传人:b****6 文档编号:5636709 上传时间:2022-12-29 格式:DOCX 页数:11 大小:160.49KB
下载 相关 举报
操作系统课程设计.docx_第1页
第1页 / 共11页
操作系统课程设计.docx_第2页
第2页 / 共11页
操作系统课程设计.docx_第3页
第3页 / 共11页
操作系统课程设计.docx_第4页
第4页 / 共11页
操作系统课程设计.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

操作系统课程设计.docx

《操作系统课程设计.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计.docx(11页珍藏版)》请在冰豆网上搜索。

操作系统课程设计.docx

操作系统课程设计

 

计算机与信息学院

操作系统课程设计

 

专业班级

信息安全10-02班

学生姓名及学号

刘禹20103046

课程教学班号

0002

任课教师

田卫东老师

实验指导教师

田卫东老师

实验地点

逸夫实验楼507

2012~2013学年第2学期

 

1、题目:

多进程/线程编程:

哲学家问题。

设置进程/线程,描述哲学家;

随机启动哲学家,显示进程/线程执行状态;

随着线程的执行,更新显示;

编写正确的哲学家程序,设法延迟线程的执行,使之出现死锁;

编写正确的哲学家程序,保证不出现死锁;

题目描述:

哲学家问题:

由Dijkstra提出并解决,是典型的同步问题。

问题描述有多个(设为number)哲学家共用一张圆桌,分别坐在周围number个椅子上,在圆桌上有number个碗和number个筷子,他们的生活方式是交替地进行思考和进餐。

平时,一个哲学家进行思考,饥饿时便试图取用其左右最靠近他的筷子,只有在他拿到两只筷子时才能进餐,进餐完毕,放下筷子继续思考。

2、开发环境:

开发工具:

VisualC++6.0;

开发环境:

Windows下多进程/线程编程

开发语言:

C++

3、总体算法:

设哲学家人数为number(程序中赋值为5),采用哲学家问题的一种解法:

(1)采用p、v操作,哲学家拿起筷子后就持有该资源,等到吃完放下筷子后其他哲学家才能拿起该筷子;同样,哲学家需要的某筷子被其他哲学家持有时,等待,进程因而阻塞。

(2)第一个到第number-1个哲学家采用一种进程描述,先左手拿筷子,之后右手才能拿。

(3)只有最后一个哲学家定义另一进程:

必须拿右手边筷子,之后再拿左手边的筷子。

 

(4)所采用方法其实质是编号资源的方法,把筷子看为临界资源,按其序号编号,哲学家只能由小到大申请资源即为本算法。

(5)出现死锁的方法:

最后一个哲学家也是先拿左手边的筷子,再拿右手边的筷子时就容易出现死锁。

4、详细设计

1.若干常量、变量的定义:

constintnumber=5;//哲学家人数

constintsleep_time=10;//显示时间

constinteating_time=50;//吃饭显示的时间

CRITICAL_SECTIONchopstics[number];//临界资源:

筷子

CRITICAL_SECTIONcs;//控制打印的临界区变量,由于一段时间只能允许一个进程打印到屏幕,所以屏幕也为临界资源

2.状态显示函数:

定义了若干函数显示当前状态:

thingking(inti)(哲学家i正在思考),

hungry(inti)(饥饿),

pickup(inti,intj)(哲学家i拿起了筷子j),

eating(inti)(正在吃饭),

putdown(inti,intj)(哲学家i放下筷子j)。

另外定义了函数xianshi(inti),每个状态显示函数都调用该函数,显示当前调用的进程。

3.线程定义体:

(1)参数为void*i,i即为调用的进程号,由于void*表示为任意类型的指针,所以要强制类型转换:

intnum=(int)i;

(2)pv操作的实现方法:

EnterCriticalSection(),LeaveCriticalSection(),

EnterCriticalSection(&chopstics[num]);//拿起左手边的筷子

pickup(num,num);

EnterCriticalSection(&chopstics[(num+1)%5]);//拿起右手边的筷子

pickup(num,num+1);

eating(num);//吃饭

LeaveCriticalSection(&chopstics[num]);//放下左边的筷子

putdown(num,num);

LeaveCriticalSection(&chopstics[(num+1)%5]);//放下右边的筷子

putdown(num,num+1);

(3)线程主体为死循环,没有资源时阻塞

4.主进程main():

(1)main函数代码如下:

HANDLEhThread[number];

InitializeCriticalSection(&cs);

//循环建立线程0-3

for(inti=0;i

{

InitializeCriticalSection(&chopstics[i]);

hThread[i]=(HANDLE)_beginthreadex(NULL,0,ThreadFunc1,(void*)i,0,NULL);

}

//建立线程4

InitializeCriticalSection(&chopstics[number-1]);

//让其不出现死锁的定义,最后一个哲学家先拿右边筷子,再拿左边筷子

//hThread[number-1]=(HANDLE)_beginthreadex(NULL,0,ThreadFunc2,(void*)(number-1),0,NULL);

//出现死锁的定义,最后一个哲学家和其他哲学家一样,也是先拿左边筷子,再拿右边筷子

hThread[number-1]=(HANDLE)_beginthreadex(NULL,0,ThreadFunc1,(void*)(number-1),0,NULL);

//等待所有hThread有效

//等待所有线程执行完

WaitForMultipleObjects(number,hThread,true,INFINITE);

for(i=0;i

{

LeaveCriticalSection(&chopstics[i]);

CloseHandle(hThread[i]);

}

LeaveCriticalSection(&cs);

相关说明:

1)初始所有临界区都要初始化,用InitializeCriticalSection()函数。

2)线程的定义用_beginthreadex()函数。

_beginthreadex()函数的原型为unsignedlong_beginthreadex(void*security,unsignedstack_size,unsigne(__stdcall*start_address)(void*),void*arglist,/*传给线程函数的参数的指针*/unsignedinitflag,unsigned*thrdaddr);,用到该函数必须链接多线程库文件,步骤为:

projectsetting->c/c++->CodeGenerator->userun-timelibrary->MulitthreadedDLL

3)主进程最后用WaitForMultipleObjects(number,hThread,true,INFINITE);等待所有线程都执行完,否则阻塞。

由于线程定义都是死循环,不可能执行完,所以这之后的语句执行不到。

此句的作用:

一,当不出现死锁时可以一直执行线程,

二,是当出现死锁时,由于各线程阻塞也没法执行完,主进程因此也阻塞,最后出现死锁。

五、执行结果

一、不出现死锁:

二、出现死锁!

六、总结

以前没有接触过多线程编程的内容,这一次为做本课程设计完全自学了好多内容。

从网上搜了好多资料,一有不会的就XX。

做的过程中也走了些弯路。

比如开始时搞忘了数组是从0开始的,实际应是从0-(number-1),好多函数的参数搞错了;还有当初不知道怎样实现pv操作;还有开始并没有完全弄清,不清楚main函数是主进程,也是会调用的,因此开始写的程序结果也不对,然后问别人才弄清楚的;程序写完后想润色一下,想把WaitForMultipleObjects()做为if语句的条件判断,若出现死锁则显示:

出现死

锁!

,运行却并不行,想了会才知道已经出现了死锁程序就阻塞了怎么可能还会继续运行,还是因为当初没弄清。

做完后很有成就感和充实感,因为学会了很多东西,从以前对多线程一无所知,到开始入门有所了解,而且还加深了对操作系统课本相关知识的理解。

总之,做完后“感觉很好”!

现在已经注意到实践的重要,以后会多动手编程,锻炼编程能力的同时还会加深对知识的理解,同时还能培养兴趣。

七、代码

#include

#include

#include

constintnumber=5;//哲学家人数

constintsleep_time=10;//显示时间

constinteating_time=50;//吃饭显示的时间

CRITICAL_SECTIONchopstics[number];//临界资源:

筷子

CRITICAL_SECTIONcs;//控制打印的临界区变量

//////////////////////////////////////////////////////////////////////////

//状态显示函数

//显示被调用线程

voidxianshi(inti){

EnterCriticalSection(&cs);

cout<<"线程"<

"<<"";

LeaveCriticalSection(&cs);

return;

}

//正在思考

voidthinking(inti){

EnterCriticalSection(&cs);

xianshi(i);

cout<<"哲学家"<

Sleep(sleep_time);

LeaveCriticalSection(&cs);

return;

}

//正饥饿

voidhungry(inti){

EnterCriticalSection(&cs);

xianshi(i);

cout<<"哲学家"<

Sleep(sleep_time);

LeaveCriticalSection(&cs);

return;

}

//哲学家i拿起了筷子j

voidpickup(inti,intj){

EnterCriticalSection(&cs);

xianshi(i);

if(j==i)

{

cout<<"哲学家"<

-"<

}elseif(i==number-1)

{

cout<<"哲学家"<

-"<<0<

}else

cout<<"哲学家"<

-"<

Sleep(sleep_time);

LeaveCriticalSection(&cs);

return;

}

//显示正在吃饭

voideating(inti){

EnterCriticalSection(&cs);

xianshi(i);

cout<<"哲学家"<

Sleep(eating_time);

LeaveCriticalSection(&cs);

return;

}

//显示放下筷子

voidputdown(inti,intj){

EnterCriticalSection(&cs);

xianshi(i);

if(j==i)

{

cout<<"哲学家"<

+"<

}elseif(i==number-1)

{

cout<<"哲学家"<

+"<<0<

}else

{

cout<<"哲学家"<

+"<

}

Sleep(sleep_time);

LeaveCriticalSection(&cs);

return;

}

/////////////////////////////////////////////////////////////////////////

//线程定义

//用于定义哲学家1-4

UINTWINAPIThreadFunc1(void*i){

intnum=(int)i;

while

(1)

{

thinking(num);

hungry(num);

//wait=WaitForSingleObject(mutex[num],INFINITE);

EnterCriticalSection(&chopstics[num]);//拿起左手边的筷子

pickup(num,num);

//wait=WaitForSingleObject(mutex[num+1],INFINITE);

EnterCriticalSection(&chopstics[(num+1)%5]);//拿起右手边的筷子

pickup(num,num+1);

eating(num);

LeaveCriticalSection(&chopstics[num]);//放下左边的筷子

//ReleaseMutex(mutex[num]);

putdown(num,num);

//ReleaseMutex(mutex[num+1]);

LeaveCriticalSection(&chopstics[(num+1)%5]);//放下右边的筷子

putdown(num,num+1);

}

return1;

}

//用于定义哲学家5

UINTWINAPIThreadFunc2(void*i){

intnum=(int)i;

while

(1)

{

thinking(num);

hungry(num);

//wait=WaitForSingleObject(mutex[0],INFINITE);

EnterCriticalSection(&chopstics[0]);//拿起右手边的筷子

pickup(num,0);

//wait=WaitForSingleObject(mutex[num],INFINITE);

EnterCriticalSection(&chopstics[num-1]);//拿起左手边的筷子

pickup(num,num);

eating(num);

//ReleaseMutex(mutex[0]);

LeaveCriticalSection(&chopstics[0]);//放下左边的筷子

putdown(num,0);

//ReleaseMutex(mutex[num]);

LeaveCriticalSection(&chopstics[num-1]);//放下右边的筷子

putdown(num,num);

}

return1;

}

//////////////////////////////////////////////////////////////////////////

intmain()

{

HANDLEhThread[number];

//HANDLEhThread2[number];

InitializeCriticalSection(&cs);

//循环建立线程0-3

for(inti=0;i

{

//mutex[i]=CreateMutex(NULL,FALSE,"");

InitializeCriticalSection(&chopstics[i]);

hThread[i]=(HANDLE)_beginthreadex(NULL,0,ThreadFunc1,(void*)i,0,NULL);

}

//建立线程4

InitializeCriticalSection(&chopstics[number-1]);

//让其不出现死锁的定义,最后一个哲学家先拿右边筷子,再拿左边筷子

//hThread[number-1]=(HANDLE)_beginthreadex(NULL,0,ThreadFunc2,(void*)(number-1),0,NULL);

//出现死锁的定义,最后一个哲学家和其他哲学家一样,也是先拿左边筷子,再拿右边筷子

hThread[number-1]=(HANDLE)_beginthreadex(NULL,0,ThreadFunc1,(void*)(number-1),0,NULL);

//等待所有hThread有效

/*if(WaitForMultipleObjects(5,hThread2,true,INFINITE))

{

cout<<"出现死锁!

"<

}*/

//等待所有线程执行完

WaitForMultipleObjects(number,hThread,true,INFINITE);

for(i=0;i

{

LeaveCriticalSection(&chopstics[i]);

CloseHandle(hThread[i]);

}

LeaveCriticalSection(&cs);

return0;

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 商务科技

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1