读写者问题Word文件下载.docx
- 文档编号:18346428
- 上传时间:2022-12-15
- 格式:DOCX
- 页数:20
- 大小:96.76KB
读写者问题Word文件下载.docx
《读写者问题Word文件下载.docx》由会员分享,可在线阅读,更多相关《读写者问题Word文件下载.docx(20页珍藏版)》请在冰豆网上搜索。
4.要求将运行过程用可视化界面动态显示,可随时暂停,查看阅览室中读者/写者数目、读者等待队列、读写时间、等待时间。
5.读写策略:
读写互斥、写写互斥、读写平等(严格按照读者与写者到达的顺入阅览室,有写着到达,则阻塞后续到达的读者;
有读者到达,则阻塞后续到达的写者)。
有一个被许多进程共享的数据区,这个数据区可以是一个文件,或者主存的一块空间,甚至可以是一组处理器寄存器。
有一些只读取这个数据区的进程(reader)和一些只往数据区中写数据的进程(writer)。
以下假设共享数据区是文件。
这些读者和写者对数据区的操作必须满足以下条件:
读—读允许;
读—写互斥;
写—写互斥。
这些条件具体来说就是:
(1)任意多的读进程可以同时读这个文件;
(2)一次只允许一个写进程往文件中写;
(3)如果一个写进程正在往文件中写,禁止任何读进程或写进程访问文件;
(4)写进程执行写操作前,应让已有的写者或读者全部退出。
这说明当有读者在读文件时不允许写者写文件。
1.4时间安排
1)分析设计贮备阶段(1天)
2)编程调试阶段(7天)
3)写课程设计报告、考核(2天)
第2部分实验原理分析
2.1问题描述
2.2解决办法
创建三个线性链表,分别为head1、head2、head3。
head1写入序列,head2为就绪序列,head3为执行序列。
其中head1用来存放输入进去的读者和写者的信息,head2根据读入内存的时间将head1中的读者写者的信息进行排序,并将排完序的读者与写者信息存在head2中,把head2的内容调入到执行序列head3中,从而执行要求的内容。
第3部分主要的功能模块
3.1功能流程图
图1
3.2测试用例及运行结果
(列出对于给定的输入所产生的输出结果。
只写出自己所做功能测试结果)
文件为文本文件。
文件内容为:
5(表示进程数)
1r72(表示进程名,进程类型,进程开始时间,进程运行时间)
2w23(表示进程名,进程类型,进程开始时间,进程运行时间)
3r34(表示进程名,进程类型,进程开始时间,进程运行时间)
4r53(表示进程名,进程类型,进程开始时间,进程运行时间)
5w64(表示进程名,进程类型,进程开始时间,进程运行时间)
程序运行实例如下:
1.选择2,运行界面如下:
2.选择3,运行界面如下:
3.在执行过程中按下s可以暂停进程的执行。
4.在进程暂停的情况下,按下a可以增加进程。
3.3结论
程序运行后,可以通过手动输入进程和文件读取进程,并执行读者与写者在公平竞争下的同步进程问题,另外可以实现进程的可视化显示、暂停和动态增加最后退出。
完成任务书的要求。
第4部分源代码
#include<
stdio.h>
stdlib.h>
conio.h>
#include"
windows.h"
intWmutex=1;
//互斥读写的信号量
intreadcount=0;
//读者数目
voidinput();
voidmain();
structprocess
{
intID;
//进程序号
chartype;
//进程类别(判断是读者还是写者)
intstarttime;
//进程开始时间
intneedtime;
//进程读写需要的时间
intruntime;
//进程在内存中已运行的时间
structprocess*next;
};
process*head1=NULL,*head2=NULL,*head3=NULL;
voidchoose()//选择
inta;
process*p,*q;
q=head1=(process*)malloc(sizeof(process));
FILE*fp;
scanf("
%d"
&
a);
switch(a)
{
case1:
//手动输入
inti,j;
printf("
\t\t输入进程数:
"
);
fp=fopen("
file.txt"
"
w+"
scanf("
i);
fprintf(fp,"
%d\n"
i);
for(j=1;
i>
0;
i--,j++)
{
p=(process*)malloc(sizeof(process));
q->
next=p;
printf("
\t\t第%d个进程:
\n"
j);
\t\t进程序号\t读或写\t\t开始时间\t执行时间\n\t\t"
scanf("
%d%c%d%d"
p->
ID,&
type,&
starttime,&
needtime);
fprintf(fp,"
%d%c%d%d\n"
p->
ID,p->
type,p->
starttime,p->
p->
runtime=0;
q=q->
next;
next=NULL;
}
fclose(fp);
p=head1;
head1=head1->
p->
free(p);
break;
case2:
//文件读入
if((fp=fopen("
r"
))==NULL)
文件打开失败!
system("
pause"
system("
cls"
main();
fscanf(fp,"
for(j=1;
fscanf(fp,"
p->
break;
case3:
intk;
if((fp=fopen("
printf("
\t\t进程序号\t读或写\t\t开始时间\t执行时间\n"
k=0;
for(j=0;
{
if(p->
type=='
r'
||p->
R'
)
k++;
\t\t%d\t\t%c\t\t%d\t\t%d\n"
}
j=j-k;
\t\t读者数目:
\t%d\n"
k);
\t\t写者数目:
p=head1;
system("
case4:
exit(0);
default:
\t\t您输入的有错误,请重新输入:
}
}
voidinput()//输入函数
printf(“\t\t***********读写平等策略*********\n"
\t\t\t1.人工输入进程信息\n"
\t\t\t2.文件载入进程信息\n"
\t\t\t3.查看进程信息\n"
\t\t\t4.退出\n"
\t\t************************************\n"
\t\t请选择:
choose();
voidready(inti)//进入就绪队列
process*p,*q,*j,*k;
q=head2;
intt=0;
if(head2==NULL)
q=head2=(process*)malloc(sizeof(process));
q->
t=1;
else
while(q->
next!
=NULL)
{
q=q->
}
j=(process*)malloc(sizeof(process));
j->
next=head1;
while(head1->
starttime==i)
head1=head1->
q=q->
j->
if(head1==NULL)
break;
while(p!
if(p->
k=j;
while(k->
=p)
{
k=k->
k->
next=p->
q->
p=p->
else
head1=j->
free(j);
if(t==1)
p=head2;
head2=head2->
free(p);
intwait(int&
a)
a--;
if(a<
0)
return0;
return1;
voidsignal(int&
a)
a++;
voidreader()//读写平等下的读者信息
process*p;
p=head3;
if(head3==NULL)
p=head3=(process*)malloc(sizeof(process));
while(p->
if(readcount>
next=head2;
p=p->
readcount++;
if((readcount==0)&
&
(wait(Wmutex)==1))
elseWmutex++;
p=head3;
head3=head3->
voidwriter()//读写平等下的写者信息
if((wait(Wmutex)==1)&
(head3==NULL))
head3=head2;
head3->
voidadd(inti)//动态增加
q=(process*)malloc(sizeof(process));
\t\t进程序号:
scanf("
q->
ID);
\t\t\t读或写:
fflush(stdin);
%c"
type);
\t\t开始时间:
q->
starttime=a+i;
\t\t执行时间:
if(head1!
next=q;
head1=q;
voidprint(inti)//输出函数
process*p;
while(p!
p->
runtime++;
printf("
\n\t\t执行%d:
\t\t执行队列:
"
if(p==NULL)
printf("
<
空>
while(p!
%d"
p=p->
\n\t\t等待队列:
voidleave()//离开执行队列
p=q=(process*)malloc(sizeof(process));
while(head3!
if(head3->
needtime!
=head3->
runtime)
next=head3;
else
if((head3->
)||(head3->
))
readcount--;
if(readcount==0)
signal(Wmutex);
else
signal(Wmutex);
head3=head3->
head3=q->
free(q);
voidmain()
inti=0;
input();
while((head1!
=NULL)||(head2!
=NULL)||(head3!
=NULL))
i++;
if(head1!
ready(i);
if(head2!
while((head2->
)||(head2->
reader();
if(head3!
w'
W'
break;
if(head2==NULL)
if((head2->
writer();
print(i);
leave();
Sleep(1000);
//交出线程占用CPU时间一秒钟
fflush(stdin);
//清空缓冲区
charch='
'
;
if(kbhit()==1)//检查当前是否有键盘输入,若有则返回一个非0值,否则返回0
ch=getch();
if((ch=='
S'
)||(ch=='
s'
{
\t\t已暂停,任意键继续...\n添加新的进程输入a\n"
ch=getchar();
}
if((ch=='
A'
a'
))
add(i);
\n\n\t\t执行完毕\n"
Wmutex=1;
readcount=0;
while
(1);
五总结
5.1总结
1)多线程编程对于解决一些并发性的问题是很高效的,而且也很必要,现在学会了使用多线程编程,对于以后解决类似的并发性问题(例如网络编程中经常遇到的多客户线程同时访问的问题),都会很有用。
2)虽然我们学习的操作系统理论课里面说多线程间的执行顺序具有随机性和不确定性,但我们毕竟是在一个特定的操作系统平台上实验,Windows的线程调度机制我是不得而知的,所以出现的一些奇怪的问题也很难调试,只好人为地去
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 读写 问题
![提示](https://static.bdocx.com/images/bang_tan.gif)