操作系统课程设计Word下载.docx

上传人:b****3 文档编号:7754672 上传时间:2023-05-09 格式:DOCX 页数:27 大小:697.72KB
下载 相关 举报
操作系统课程设计Word下载.docx_第1页
第1页 / 共27页
操作系统课程设计Word下载.docx_第2页
第2页 / 共27页
操作系统课程设计Word下载.docx_第3页
第3页 / 共27页
操作系统课程设计Word下载.docx_第4页
第4页 / 共27页
操作系统课程设计Word下载.docx_第5页
第5页 / 共27页
操作系统课程设计Word下载.docx_第6页
第6页 / 共27页
操作系统课程设计Word下载.docx_第7页
第7页 / 共27页
操作系统课程设计Word下载.docx_第8页
第8页 / 共27页
操作系统课程设计Word下载.docx_第9页
第9页 / 共27页
操作系统课程设计Word下载.docx_第10页
第10页 / 共27页
操作系统课程设计Word下载.docx_第11页
第11页 / 共27页
操作系统课程设计Word下载.docx_第12页
第12页 / 共27页
操作系统课程设计Word下载.docx_第13页
第13页 / 共27页
操作系统课程设计Word下载.docx_第14页
第14页 / 共27页
操作系统课程设计Word下载.docx_第15页
第15页 / 共27页
操作系统课程设计Word下载.docx_第16页
第16页 / 共27页
操作系统课程设计Word下载.docx_第17页
第17页 / 共27页
操作系统课程设计Word下载.docx_第18页
第18页 / 共27页
操作系统课程设计Word下载.docx_第19页
第19页 / 共27页
操作系统课程设计Word下载.docx_第20页
第20页 / 共27页
亲,该文档总共27页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

操作系统课程设计Word下载.docx

《操作系统课程设计Word下载.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计Word下载.docx(27页珍藏版)》请在冰点文库上搜索。

操作系统课程设计Word下载.docx

3.2主函数流程图4

3.3理发师进程流程图5

3.4顾客进程流程图5

3.5函数调用6

第四章.详细设计7

4.1概要设计7

4.1.1数据结构7

4.1.2多线程编译原理7

4.1.3创建线程7

4.1.4信号量8

4.2头文件声明8

4.3函数定义9

4.4变量定义9

4.5函数实现9

第五章.调试与测试11

5.1调试方法11

5.2结果分析13

第六章.设计中遇到的问题及解决方法14

6.1出现的问题14

6.2解决方法14

第七章.源程序清单和执行结果16

7.1源程序清单16

7.2程序执行结果19

第八章.心得体会20

第九章.参考文献21

第一章.系统环境

1.1硬件环境

内存1GB,处理器1,硬盘(SCSI)50GB,网络适配器NAT。

1.2软件环境

虚拟机上运行的Red 

Hat 

Linux 

9系统运行环境,言语开发环境是Linux的GNUC或C++。

图1.1软件环境

第二章.设计目的及要求

2.1设计目的

学习计算机软件技术,特别是计算机操作系统技术,除了需要刻苦努力外,还需要掌握软件和操作系统的原理与设计技巧。

但由于条件和学时有限,在理论学习过程中没有给提供更多的实验机会。

本操作系统课程设计,是提供了一个集中实验的机会。

应该通过该设计加深对所学习课程的理解。

进一步研究和实践操作系统中关于并发进程同步与互斥操作的一些经典问题的解法。

加深对于非对称性互斥问题有关概念的理解。

观察和体验非对称性互斥问题的并发控制方法。

进一步了解Linux系统中进程同步工具的用法,训练解决对该类问题的实际编程、调试和分析问题的能力。

2.2要求

按件工程的思想和方法进行设计,并把它作为一个工程来做。

设计的每一步都有要形成文档,“成品”出来以后要有使用说明书和测试报告。

最后按院方统一要求整理出软件实习“论文”,并分别以电子和书面文档的形式上交。

最后,设计的程序要编译通过,并在验收时进行演示。

本设计的内容是基于《操作系统原理》教材的,但同学们必须对以前的《C语言程序设计》和《数据结构》等内容进行认真的复习。

本设计是基于课程中学到的UNIX系统调用,使用操作系统环境是RedHatLinux9,言语开发环境是Linux的GNUC或C++。

因此,要求课程设计者对Linux操作系统和GNUC或C++有一定的了解。

2.3内容

(1)一个理发店接待室有n张椅子,工作室有1张椅子;

(2)没有顾客时,理发师睡觉;

(3)第一个顾客来到时,必须将理发师唤醒;

(4)顾客来时如果还有空座的话,他就坐在一个座位上等待;

(5)如果顾客来时没有空座位了,他就离开,不理发了;

(6)当理发师处理完所有顾客,而又没有新顾客来时,他又开始睡觉。

第三章.总体设计

题目中要求描述理发师和顾客的行为,因此需要进程barber()和customer()分别描述理发师和顾客的行为。

当理发师看报时顾客近来需要唤醒理发师为其理发,当有顾客时理发师为其理发,没有的时候理发师休息,因此理发师和顾客之间是同步的关系,由于每次理发师只能为一个人理发,且可供等侯的椅子有限只有n个,即理发师和椅子是临界资源,所以顾客之间是互斥的关系。

故引入3个信号量和一个控制变量:

1)控制变量waiting用来记录等候理发的顾客数,初值均为0;

2)信号量customers用来记录等候理发的顾客数,并用作阻塞理发师进程,初值为0;

3)信号量barbers用来记录正在等候顾客的理发师数,并用作阻塞顾客进程,初值为0;

4)信号量mutex用于互斥,初值为1;

3.1程序设计组成框图

实现工具及方法

基本

事项

LINUX+C语言+VMware workstation

工作

睡觉

理发师barber等待顾客理发,如果没有顾客就去睡觉,否则顾客获得理发椅使用权,过后释放理发椅使用权。

创建

线程

创建理发师线程,初始化信号量sem_init(&

barbers,0,1);

,如果创建失败,exit(EXIT_FAILURE)

剪发

等待

顾客customer理发,如果等待室有空位,进入。

如果理发师在睡觉唤醒理发师,如果在工作就在等待室等候。

创建顾客线程,初始化信号量sem_init(&

customers,0,0);

如果创建失败,exit(EXIT_FAILURE)

图3.1

3.2主函数流程图

在程序模块中,主要实现对线程的操作,开始创建理发师进程,只有当顾客到来时再创建顾客线程来实现对顾客的操作,开始理发,当顾客全部理发完成时,就睡觉结束所有线程。

图3.2主函数流程图

3.3理发师进程流程图

再理发师模块中,但有顾客来时,理发师线程开始申请顾客信号量,顾客减一,理发师理发,完成时,释放理发师信号量。

如归偶没有顾客就睡觉。

图3.3理发师进程流程图

3.4顾客进程流程图

在顾客模块中,当一个顾客来的时候,判断顾客人数要小于椅子数,如果没有空椅子顾客离去,如果有,顾客等待且顾客人数加1,释放顾客信号量,等待理发师理发。

图3.4顾客流程图

3.5函数调用

根据设计要求主函数天妖一下三个主要函数,来完成本程序,主函数main实现对两个线程的控制和执行操作。

图3.5函数调用关系图

第四章.详细设计

4.1概要设计

4.1.1数据结构

sem_tcustomers;

sem_tbarbers;

pthread_mutex_tmutex;

intwaiting=0;

intchair[CHAIRS];

intcus[people];

4.1.2多线程编译原理

此次在Linux下进行多线程编程需要用到pthread_create、pthread_mutex_lock和pthread_mutex_unlock这三种函数

4.1.3创建线程

pthread_create用来创建一个线程,原型为:

intpthread_create((pthread_t*__thread,__constpthread_attr_t*__attr,void*(*__start_routine)(void*),void*__arg))

第一个参数为指向线程标识符的指针,第二个参数用来设置线程属性,第三个参数是线程运行函数的起始地址,最后一个参数是运行函数的参数。

函数thread不需要参数时,最后一个参数设为空指针。

第二个参数设为空指针时,将生成默认属性的线程。

创建线程成功后,新创建的线程则运行参数三和参数四确定的函数,原来的线程则继续运行下一行代码。

pthread_create(&

ntid,NULL,thr_fn,NULL):

线程创建函数

原型:

intpthread_create(pthread_t*thread,constpthread_attr_t*attr,void*(*start_routine)(void*), 

void*arg)。

tid:

新创建线程的线程ID;

attr:

指定新创建线程的线程属性,为NULL即为使用默认属性;

start_routine:

这是一个函数指针,用来指向线程函数;

arg:

传递给线程函数的指针;

返回值:

0代表成功。

失败,返回的则是错误号。

4.1.4信号量

(1)函数sem_init()用来初始化一个信号量,函数原型为:

intsem_init(sem_t*__sem,intpshared,unsignedvalue));

该函数将sem引用的无名变量初始化为value,该参数表示拥有资源的个数,不能为负数。

sem为指向信号量结构的一个指针;

pshared不为0时此信号量在进程间共享,否则只能为当前进程的所有线程共享;

value给出了信号量的初始值。

(2)sem_post函数的作用是给信号量的值加上一个“1”,它是一个“原子操作”即同时对同一个信号量做加“1”操作的两个线程是不会冲突的;

而同时对同一个文件进行读、加和写操作的两个程序就有可能会引起冲突。

信号量的值永远会正确地加一个“2”,因为有两个线程试图改变它。

当有线程阻塞在这个信号量上时,调用这个函数会使其中一个线程不在阻塞,选择机制是有线程的调度策略决定的。

(3)sem_wait函数也是一个原子操作,它的作用是从信号量的值减去一个“1”,但它永远会先等待该信号量为一个非零值才开始做减法。

也就是说,如果你对一个值为2的信号量调用sem_wait(),线程将会继续执行,这信号量的值将减到1。

如果对一个值为0的信号量调用sem_wait(),这个函数就会地等待直到有其它线程增加了这个值使它不再是0为止。

4.2头文件声明

#include<

pthread.h>

#include<

stdio.h>

unistd.h>

stdlib.h>

semaphore.h>

sys/time.h>

math.h>

4.3函数定义

voidbarber(void):

定义一个理发师函数

voidcustomer(intnum):

定义一个顾客函数

voidcut_hair(void):

定义一个理发时间函数

sleep():

执行挂起一段时间,在gcc编译器中,使用的头文件因gcc版本的不同而不同,#include<

,单位为秒,返回值若进程/线程挂起到参数milliseconds所指定的时间则返回0,若有信号中断则返回剩余秒数。

在Linux下,sleep中的“s”不大写

pthread_mutex_lock(&

mutex);

//加锁

pthread_mutex_unlock(&

//释放锁

sem_wait(&

customers);

相当于wait(customers)减一

sem_post(&

barbers);

//相当于signel(barber)加一

sem_init(&

//initialofthecustomersis0顾客信号量

//initialofthebarbersis1理发师信号量

4.4变量定义

1.intwaiting=0;

//thenumberofwaitingcustomers

2.intchair[CHAIR];

//椅子数组

3.intcus[people];

//顾客数组

4.inti;

//用于数组下标

5.intser;

//椅子编号

6intseq;

4.5函数实现

voidbarber(void);

voidcustomer(intnum);

voidcut_hair(void);

//initialofthecustomersis0顾客信号量

//initialofthebarbersis1理发师信号量

✧理发师线程

voidbarber(void)//理发师线程

{

while

(1)//循环

{sem_wait(&

//wait(customers)

pthread_mutex_lock(&

//上互斥锁

waiting=waiting-1;

//等待的顾客减一个

Printf("

customer%disgoingtobeserved!

\n"

chair[ser]);

//ser座位编号

chair[ser]=0;

//该座位上的顾客离开等待座位到理发座位理发

ser=(ser+1)%CHAIRS;

//查找下一个被理发的顾客

pthread_mutex_unlock(&

//释放锁

cut_hair();

//理发函数,延迟时间

sem_post(&

//signal(barbers)

}

}

✧顾客线程

voidcustomer(intnum)//num顾客编号变量

intk;

pthread_mutex_lock(&

//解锁

if(waiting<

CHAIRS)//顾客进入时有空位

{

waiting=waiting+1;

//等待着的顾客加一

//signal(customers)

printf("

Customer%d,Youshouldsitatthe%dseat!

num,seq);

//seq座位编号

chair[seq]=num;

//第num个顾客坐在seq个座位上,座位数组的值为顾客的编号

seq=(seq+1)%CHAIRS;

//seq移动到下一个座位

for(k=0;

k<

CHAIRS;

k++)

if(chair[k]!

=0)//查询座椅上的顾客,如果chair为0,则座位上没有顾客

printf("

customer%disatseat!

chair[k]);

//输出座位上顾客的编号

else

empty!

);

//释放锁

sem_wait(&

//wait(barber),如果成功,则执行理发师程序,失败转为等待

}else//顾客进入时没有座位

{printf("

Customer%d,Youshouldleave.Therearesomanypeople!

num);

第五章.调试与测试

5.1调试方法

在电脑上编写代码,将代码拷贝到Linux系统虚拟机上。

然后在虚拟机上使用vi编译器对C语言代码进行编译,存放C语言代码的文件名为jiami.c。

编译语句为gcc–lpthread-opanpan.c。

执行代码语句为./pan。

看文件的状态情况。

最后完成调试和测试,程序成功执行,得到正确的结果。

测试结果的分析与讨论:

1.对文件pan.c进行查看。

图5.1

2.编译并执行程序pan.c。

图5.2

3.得到测试结果。

图5.3

图5.4

图5.5

5.2结果分析

程序成功运行,对文件的操作如图5.3~5.6所示,成功对理发师问题进行解决。

在调试过程中出现一些问题,但是查阅资料就解决了,像编译语句为gcc–lpthread-opanpan.c,自己第一次输编译语句为gcc-opanpan.c就出现错误,因为在线程里是不对的,找不到线程的头文件。

✧测试过程中遇到的主要问题

编译语句为gcc–lpthread-opanpan.c,自己第一次输编译语句为gcc-opanpan.c就出现错误,因为在线程里是不对的,找不到线程的头文件。

会出现输入错误。

在Linux虚拟机中vi编译器编译时会出现错误,像res=pthread_create(&

barber_t,NULL,barber,NULL);

提示找不到barber的指针,虽然可以运行结果,但还是不对,经过上网查看资料解决了这个问题。

✧解决措施

按部就班地执行程序,按出错提示寻找错误的地方,问同学和老师、上网查看结果分析,XX了好多重要的东西,还有程序的完善,在这次课程设计中,程序也是一遍一遍地被修改。

终于做好了这次的课程设计。

耐心、细心和发现问题的能力是做程序的根本。

第六章.设计中遇到的问题及解决方法

6.1出现的问题

✧问题一

图6.1

✧问题二

图6.3

6.2解决方法

在这个编程中,虽然源代码算没错,不过在运行时就有问题,在调试中前后函数的功能要对应,要不然就不能正确运行,还有一些基本的符合不符合规范,注意英文字母的书写,例如在LNIUX中sleep()中s要小写,注意书写代码的规范,gcc-opanpan.c在执行的时候就会出错如图6.2,因为在线程创建中需要pthread_create,所以要用–lpthread来找到#include<

pthread>

的头文件才可以执行。

还有像图6.1找不到那几种指针,经上网查阅后修改正确了。

所以细心观察程序的逻辑结构,认真分析程序的流程。

同组的人员共同讨论,集思广益,规范代码,完善功能。

图6.4

图6.5

第七章.源程序清单和执行结果

7.1源程序清单

#defineCHAIRS5

#definepeople20

inti;

intseq=0;

intser=0;

voidbarber(void);

intmain()

{

intres;

pthread_tbarber_t;

pthread_tcustomer_t;

sem_init(&

pthread_mutex_init(&

mutex,NULL);

//initialofthemutexis0

for(i=0;

i<

i++)

{chair[i]=0;

people;

{cus[i]=i+1;

res=pthread_create(&

barber_t,NULL,(void*)barber,NULL);

if(res!

=0)

Barberthreadcreationfailed!

exit(EXIT_FAILURE);

else

I'

mabarber!

You'

reWelcome!

for(i=1;

people+1;

printf("

m%dcustomer!

Iamcoming!

i);

customer_t,NULL,(void*)customer,(void*)cus[i-1]);

costomer%dthreadcreationfailed!

if(i<

people)

sleep(rand()%4);

else

sleep

(2);

}

voidbarber(void)

{while

(1)

{sem_wait(&

waiting=waiting-1;

chair[ser]=0;

ser=(ser+1)%CHAIRS;

pthread_mutex_unlock(&

cut_hair();

sem_post(&

}

voidcut_hair(void){

Barber:

Iamcuttingthecustomer'

shair......\n"

sleep(3);

Done!

voidcustomer(intnum)

{intk;

CHAIRS)

{waiting=waiting+1;

Customer%d,Youshould

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

当前位置:首页 > 医药卫生 > 药学

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2