课程
设计
领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计
:采用“写优先”的策略演示“读者-写者”
摘要
一个数据文件或记录可被多个进程共享,把只要求读该文件的进程称为“Reader进程”,其他进程则称为“Writer进程”。允许多个进程同时读一个共享对象,因为读操作不会使数据文件混乱。但不允许一个Writer进程和其他Reader进程或Writer进程同时访问共享对象。因为这种访问会引起混乱。
所谓“读者-写者问
题
快递公司问题件快递公司问题件货款处理关于圆的周长面积重点题型关于解方程组的题及答案关于南海问题
”指保证一个Writer进程必须与其他进程互斥地访问共享对象的同步问题。
目录
1. 概述 ...................................................................... 3 2.课程设计任务及要求 ......................................................... 4
2.1 设计任务 ............................................................. 4
2.2 设计要求 ............................................................. 4
算法及数据结构 ............................................................ 5 3.
3.1 算法的总体思想 ....................................................... 5 3.1
3.2 键入读者/写者进程模块 ................................................ 5 3.2
3.3 读取读者/写者样例模块 ................................................ 6 3.3
3.4 查看读者写者信息模块 ................................................. 7 4. 程序设计与实现 ............................................................ 8
4.1 程序
流程
快递问题件怎么处理流程河南自建厂房流程下载关于规范招聘需求审批流程制作流程表下载邮件下载流程设计
图. .......................................................... 8
4.2 主要程序代码 ......................................................... 8
4.3 实验结果 ............................................................ 14 5. 结论 ..................................................................... 17 6. 收获、体会和建议。 ....................................................... 18
6.1谢海钊的收获体会 ..................................................... 18
6.2叶诗敏的收获体会 ..................................................... 18 7. 参考文献。 ............................................................... 18
1.概述
所谓读者写者问题,是指保证一个Writer进程必须与其他进程互斥地访问共享对象的同步问题。写优先的读者写者问题可以这样的描述,有一群写者和一群读者,写者在写同一本
书
关于书的成语关于读书的排比句社区图书漂流公约怎么写关于读书的小报汉书pdf
,读者也在读这本书,多个读者可以同时读这本书,但是,只能有一个写者在写书,并且,写者的优先级必须比读者的大,也就是说,读者和写者同时提出请求时,写者优先执行。
2.课程设计任务及要求
2.1 设计任务 2.1 设计任务
成员姓名 周三下午 周四上午 周四下午 周五上午 周五下午 谢海钊 查找相关资了解算法,调
分析
定性数据统计分析pdf销售业绩分析模板建筑结构震害分析销售进度分析表京东商城竞争战略分析
、修改代完善代码,测完善课程设
料 试代码 码 试 计报告 叶诗敏 查找相关资了解算法,调写报告,画程测试 完善课程设
料 试代码 序流程图 计报告
2.2 设计要求 2.2 设计要求
1) 读者与写者至少包括ID、进入内存时间、读写时间三项内容,可在界面上进行输入 2) 读者与写者均有二个以上,可在程序运行期间动态增加读者与写者 3) 可读取样例数据(要求存放在外部文件中),进行读者/写者、进入内存时间、读写
时间的初始化
4) 要求将运行过程用可视化界面动态显示,可随时暂停,查看阅览室中读者/写者数目、
读者等待队列、写者等待队列、读写时间、等待时间
5) 读写策略为:读写互斥、写写互斥、写优先(只要写者到达,就阻塞后续的所有读
者,一旦阅览室无人,写者能最快进入阅览室;在写者未出阅读室之前,又有新的
读者与写者到达,仍然是写者排在前面)
3.算法及数据结构
3.1 算法的总体思想 3.1 算法的总体思想
本算法主要使用互斥信号量机制,解决读者写者同步问题。本算法通过创建三个链表process1,process2和process3,process1用于存储各个进程的信息,process2用于存储就绪队列的进程信息,process3用于存储正在执行的进程的信息。通过使用整形变量来模拟时间片,每次时间片一开始,通过ready()函数将进程拉入就绪队列。然后根据判断就绪队列的开头是读者还是写者,来调用相应的进程Reader()或Writer()。如果调用的是Writer(),就得调用sort()函数对就绪队列进程进行排序,将写者排在读者前面。当时间片结束时,对各个进程的执行时间加1,并判断进程是否执行完毕,如果完毕就将其退出运行进程链表process3。最后将时间片加一,反复循环,直到所有进程执行完毕。
本系统主要有三个模块,键入读者写者进程模块、读取读者写者样例模块、查看读者写者信息模块。
定义进程结构体:
struct Process {
int name; //进程序号
char type; //进程类别(判断是读者进程还是写者进程)
int starttime; //进程开始执行时间
int needtime; //进程读写需要的时间
int runtime;//进程已在内存中运行的时间
struct Process *next; //指向下一个进程的指针
};
3.2 键入读者/写者进程模块 3.2 键入读者/写者进程模块
3.2.1 功能
通过键盘录入读者写者进程数和读者写者信息,系统根据写优先的策略来调度相应
的读者写者进程,并输出相应的执行序列。
3.2.2 数据结构
Process *process1=NULL,*process2=NULL,*process3=NULL; //定义三个指针变量,分别
用于存储各个进程的信息,存储就绪队列的进程信息,存储可执行的进程的信息
3.2.3 算法
开始
录入进
程信息
拉进就绪队列
判断读者还RW是写者
读者写者
否运行时间+1排序
判断运行时间是否等于所
需时间
是
退出执行链表否
进程是否完毕
是 结束
3.3 读取读者/写者样例模块 3.3 读取读者/写者样例模块
3.3.1 功能
该模块主要通过读取外部样例数据,进行读者/写者、进入内存时间、读写时间的初始化,并输出读者写者进程执行情况。
3.3.2 数据结构
Process *process1=NULL,*process2=NULL,*process3=NULL; //定义三个指针变量,分别用于存储各个进程的信息,存储就绪队列的进程信息,存储可执行的进程的信息 FILE *fp; //声明fp是指针,用来指向FILE类型的对象,存取外部文件信息
3.3.3 算法
开始
读取进
程信息
拉进就绪队列
判断读者还RW是写者
读者写者否运行时间+1排序
判断运行时间是否等于所
需时间
是
退出链表3否
进程是否完毕
是
结束3.4 查看读者写者信息模块 3.4 查看读者写者信息模块
3.4.1 功能
查看当前系统中读者写者进程的数量及信息。
3.4.2 数据结构
Process *p,*q; //定义进程变量指针,用于存储读者写者信息 3.4.3 算法
开始
读取读者写
者信息文件
是否存在读者
写者,
是
输出读者写否
者数目及信
息
结束
4.程序设计与实现
4.1 程序流程图. 4.1 程序流程图.
开始
Ready int(i)
rwtype
Reader()Writer()
Runtime++Sort()
i++
Runtime==needtime
T
F离开process3
Process1,Fprocess2,process3均为空
T
结束4.2 主要程序代码 4.2 主要程序代码
struct Process //定义结构体
{ int name; //进程序号
char type; //进程类别(判断是读者还是写者)
int starttime; //进程开始时间
int needtime; //进程读写需要的时间
int runtime; //进程在内存中已运行的时间
struct Process *next; //指向下一个进程的指针
};
Process *process1=NULL,*process2=NULL,*process3=NULL; //定义三个进程变量指针,分别用于存储各
个进程的信息,存储就绪队列的进程信息,存储可执行的进程的信息 int wait(int &a) //请求信号量
{ if(a<=0) //资源不足
{ return 0; }
a--; //资源数量减1
return 1; }
void signal(int &a) //唤醒信号量
{ a++; //资源数量加1}
void Reader() // 读者进程
{ Process *p;
int t=0;
p=process3; //将运行进程信息赋给指针变量p
if(process3==NULL)
{ p=process3=(Process *)malloc(sizeof(Process)); //进程执行链表为空,为其分配动态存储空间
p->next=NULL;
t=1; }
else //进程执行链表不为空,进程执行
{ while(p->next!=NULL)
{ p=p->next; } }
if(readcount>0)
{ //判断存在读者, 把读者进程插入就绪链表
p->next=process2;
process2=process2->next;
p=p->next;
p->next=NULL;
readcount++;//读者数量加1
}
if((readcount==0)&&(wait(mutex)==1)) //没有读者,并且获得阅读的权限,将其拉入就绪队列
{ p->next=process2;
process2=process2->next;
p=p->next;
p->next=NULL;
readcount++;//读者数目加1
}
if(t==1)//不存在运行的进程
{ p=process3;
process3=process3->next;
p->next=NULL;
free(p); //释放运行进程链表空间
} }
void Writer()//写者进程
{ if((wait(mutex)==1)&&(process3==NULL)) //判断进程运行链表是否为空,并且是否获得写的机会
{ process3=process2; //把就绪队列中的写者进程装入执行链表
process2=process2->next;
process3->next=NULL;
} }
int main() //主函数
{ printf("\t\t****************==================****************\n");
printf("\t\t************* 写优先的读者写者问题 *************\n");
printf("\t\t****************==================****************\n");
printf("\t\t## ##\n");
int i=0;
Process *p,*q;
input(); //程序主模块
printf("\n以下输出各进程执行状态\n");
printf("<键入p可暂停执行>\n");
sleep(1); //暂停一秒
while((process1!=NULL)||(process2!=NULL)||(process3!=NULL))
{ i++;
if(process1!=NULL) //存在进程信息,拉入就绪队列
ready(i); //调用就绪函数
if(process3!=NULL) //存在可执行进程
if((process3->type=='w')||(process3->type=='W'))
sort(); //判断为写者进程,执行排序
sort();
if(process2!=NULL) //就绪链表不为空
while((process2->type=='r')||(process2->type=='R')) //为读操作
{ Reader(); 调入读者进程
if(process3!=NULL) //存在可执行进程
if((process3->type=='w')||(process3->type=='W')) //判断是否为写者
break;
if(process2==NULL) //就绪链表为空
break;
} if(process2!=NULL) //就绪链表不为空
if((process2->type=='w')||(process2->type=='W'))
{ Writer(); //调用写着进程
sort(); //排序 }
p=process3;
while(p!=NULL)
{ p->runtime++; //执行时间加1
p=p->next; }
printf("\n时间 %d :\n",i);
printf("\t正执行进程: ");
p=process3; //将运行进程链表赋给指针变量p
if(p==NULL)
printf("<空>");
else
while(p!=NULL)
{ printf("%d ",p->name);
p=p->next; }
printf("\n\t就绪队列: ");
p=process2; //将就绪链表赋给指针变量p
if(p==NULL) //就绪链表为空
printf("<空>");
else
while(p!=NULL) //就绪链表不为空
{ printf("%d ",p->name);//输出就绪进程信息
p=p->next; }
printf("\n");
p=q=(Process *)malloc(sizeof(Process));
p->next=NULL;
while(process3!=NULL) //可执行进程链表不为空
{ if(process3->needtime!=process3->runtime)//运行时间不
等于需要的时间,继续执行
{ p->next=process3;
p=p->next; }
else //运行完成
{ if((process3->type=='r')||(process3->type=='R'))
{ readcount--; 读者读完,读者数目减1
if(readcount==0) //不存在读者
signal(mutex);//唤醒互斥信号量 }
else
signal(mutex); //唤醒互斥信号量}
process3=process3->next; //指向执行链表的下一个进程
p->next=NULL;}
process3=q->next;
q->next=NULL;
free(q);
sleep(2);
if(kbhit()==1)//检查当前是否有键盘输入,若有则返回一个非0值,否则返回0
{ char ch;
ch=getchar();
if((ch=='p')||(ch=='P'))
{ printf("\n已暂停,继续请按P\n");
printf("如需添加进程请按A\n"); aa:
fflush(stdin);
ch=getchar();
if((ch=='A')||(ch=='a'))
{ add(i); //添加读者写者
printf("添加完成!\n");}
fflush(stdin);
while(1)
{ if((ch=='P')||(ch=='p')) //判断是否暂停操作
break;
else
goto aa;
}
}
}
}
printf("\n\n所有进程执行完毕\n");
printf("按回车键继续。。。\n");
getchar();
system("reset");
//pause();//暂停
main(); //调用主函数
while(1);
return 0; }
4.3 实验结果 4.3 实验结果
程序运行结果如下:
键入读者/写者进程模块效果图:
读取读者/写者样例模块效果图:
查看读者写者信息模块效果图:
5.结论
通过使用互斥信号量机制,用PV操作,可以解决读者写者共享临界资源问题。在读者写者同时在队列中等待申请资源时,写者优先调用资源。而且如果一个读者申请进行读操作时已有另一读者正在进行读操作,则该读者可直接开始读操作,即读读允许,如果既有读者又有写者,则写者先于读者执行,一个写者与其他读者或写者互斥执行。
6.收获、体会和建议。
6.1 谢海钊的收获体会 6.1 谢海钊的收获体会
这次课程设计让我对进程之间访问共享对象的同步问题有了更加深刻的理解,同时更加熟练的使用PV操作来解决进程之间的同步问题。更加灵活的在Linux下编辑、运行C语言程序,对程序设计思想也有了比较清晰的印象。总的感觉,学到了很多知识,对于linux有了进一步的了解,当然在课程设计过程中也遇到好多问题,因为这学期刚接触Linux,特别在Linux下编写C程序,Linux下有些库函数跟在Windows上的不一样,导致在Windows上能运行的程序在Linux上运行不了,通过分析错误,查找相关资料,最终解决了。这次课程设计让我更加明白只要细心耐心的去处理每个问题,问题就会迎刃而解。 6.2 叶诗敏的收获体会 6.2 叶诗敏的收获体会
这一次课程设计,让我体会很深刻。通过查找资料,了解了采用写优先读者写者问题,我对并发进程应用有了深入的了解。了解支持多道程序的并发操作系统设计中解决资源共享时进程间的同步与互斥的信号量机制。更加系统地理解和掌握C语言的基本概念、语言特点和编程技巧,在应用C语言在程序设计方面得到系统锻炼,同时了解了在window下运行的命令有时候在Linux下运行是不行的,通过查找资料,和同学讨论。虽然有难度的东西总会让人很抵触,遇到困难,但是通过跟同学讨论,和上网查找资料,在这个过程中能够磨练人的意志与耐心。
7.参考文献。
【1】《操作系统》(第三版).汤小丹,梁红兵.西安电子科技大学出 版社.2007 【2】《C程序设计语言》.(第三版)谭浩强.清华大学出版社.2004 【3】《数据结构》 (C语言版).严蔚敏 ,吴伟民.清华大学出版社.2007 【4】百度搜索引擎