读者写者问题

河北科技大学操作系统课程设计——读者写者问题

#include <windows.h>
#include <conio.h>
#include <stdlib.h>
#include <fstream>
#include <io.h>
#include <string.h>
#include <stdio.h>
using namespace std;
#define READER 'R'
#define WRITER 'W'
#define MAX_THREAD_NUM 32 //最大线程数目
CRITICAL_SECTION RP_Write; //临界区
CRITICAL_SECTION pright; //权限 
CRITICAL_SECTION w_Mutex; //临界区
CRITICAL_SECTION cs;//对输出格式加锁控制 
#define INTE_PER_SEC 100  //每秒时钟中断数目int flag;
int readcount=0;          //读者数目
int writecount=0;         //写者数目
struct ThreadInfo
{	int serial;           //线程序号char entity;          //线程类别double delay;         //线程开始时间double persist;       //线程读写持续时间
};
ThreadInfo  thread_info[MAX_THREAD_NUM]; 
//读者优先处理函数
void ReaderPriority(int num);   
void RP_ReaderThread(void *p);
void RP_WriterThread(void *p);
//写者优先处理函数
void WriterPriority(int num);  
void WP_ReaderThread(void *p);
void WP_WriterThread(void *p);//显示函数
void showInput(void);
void showWhich(void); 
int main()
{InitializeCriticalSection(&cs);int num;int choice; while(1){system("cls");showInput();scanf("%d",&choice);switch(choice){case 1:system("cls");showWhich();break;case 2:exit(1); break;default :printf("输入有误,请重新输入!\n");Sleep(1000);break;}}system("pause");      return 0;
}
void showInput(void)
{printf("            *********请选择功能*********\n");printf("            *                          *\n"); printf("            *    1:模拟读者写者问题    *\n");printf("            *                          *\n");  printf("            *    2:退出系统            *\n"); printf("            *                          *\n"); printf("            ****************************\n"); 
} 
void show()
{printf("            *********请选择功能*********\n");printf("            *                          *\n"); printf("            *        1:读者优先        *\n");printf("            *        2:写者优先        *\n");  printf("            *        3:返回上一级      *\n"); printf("            *        4:清屏并继续      *\n"); printf("            *        5:退出系统        *\n"); printf("            *                          *\n");printf("            ****************************\n");
}
void showWhich(void)
{int num;int choice;printf("请输入总的读者写者线程数:(<=32)\n");scanf("%d",&num);for(int i=0;i<num;i++){printf("请输入*线程号*线程类别(R/W)*线程开始时间*线程持续时间:\n");scanf("%d %c %lf %lf",&thread_info[i].serial,&thread_info[i].entity,&thread_info[i].delay,&thread_info[i].persist);	}system("cls");show();while(1){ scanf("%d",&choice); switch(choice){case 1:printf("序号  读者或写者   开始时间   持续时间\n");for(int i=0;i<num;i++){	printf(" %d        %c        %f   %f  \n",thread_info[i].serial,thread_info[i].entity,thread_info[i].delay,thread_info[i].persist);}ReaderPriority(num);//读者优先continue;case 2:printf("序号  读者或写者   开始时间   持续时间\n");for(int i=0;i<num;i++){	printf(" %d        %c        %f   %f  \n",thread_info[i].serial,thread_info[i].entity,thread_info[i].delay,thread_info[i].persist);}WriterPriority(num);//写者优先continue;case 3:flag=1;break;case 4:system("cls");show();continue; case 5:flag=0;break; default:printf("输入有误,请重新输入!\n");Sleep(1000);system("cls");show();continue; };if(flag==1) break;if(flag==0) exit(1);}
}
//读者优先处理函数
void ReaderPriority(int num)
{DWORD n_thread=num;        //线程数目DWORD thread_ID;         //线程IDDWORD wait_for_all;      //等待所有线程结束HANDLE rmutex;	//使读者互斥访问readcountrmutex=CreateMutex(NULL,FALSE,"mutex_for_readcount");// HANDLE h_Thread[MAX_THREAD_NUM];readcount=0;     //初始化readcountInitializeCriticalSection(&RP_Write);  //初始化临界区printf("读者优先:(纵坐标为执行顺序)\n");for (int i=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);}//等待所有线程结束wait_for_all=WaitForMultipleObjects(n_thread,h_Thread,TRUE,-1);printf("所有操作完成\n\n");
}
//读者优先-----读者线程
void RP_ReaderThread(void *p)
{	int m_ID;           //线程序号DWORD m_delay;      //延迟时间DWORD m_persist;    //读文件持续时间m_ID=((ThreadInfo *)(p))->serial;m_delay=(DWORD)(((ThreadInfo *)(p))->delay*INTE_PER_SEC);m_persist=(DWORD)(((ThreadInfo *)(p))->persist*INTE_PER_SEC);HANDLE rmutex;//使读者互斥访问readcountrmutex=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex_for_readcount");DWORD wait_for_mutex;   //等待互斥变量所有权Sleep(m_delay); //延迟等待EnterCriticalSection(&cs);for(int i=1;i<m_ID;i++)printf("           ");printf("读者%d读请求\n",m_ID);LeaveCriticalSection(&cs);	wait_for_mutex=WaitForSingleObject(rmutex,-1); //P(rmutex)readcount++;   //读者数目加1if (readcount==1)EnterCriticalSection(&RP_Write);  //如果这是第一个读者,进入临界区,开始执行 P(RP_Write);ReleaseMutex(rmutex);//V(rmutex)EnterCriticalSection(&cs);	for(int j=1;j<m_ID;j++)//读文件printf("           ");printf("读者%d开始读\n",m_ID);LeaveCriticalSection(&cs);Sleep(m_persist);EnterCriticalSection(&cs);for(int k=1;k<m_ID;k++)//退出线程printf("           ");printf("读者%d完成读\n",m_ID);LeaveCriticalSection(&cs);wait_for_mutex=WaitForSingleObject(rmutex,-1);  //P(rmutex)readcount--;          //读者数目减1if (readcount==0)LeaveCriticalSection(&RP_Write); //如果这是最后一个读者,则其释放临界区V(RP_Write);ReleaseMutex(rmutex); //V(rmutex)
}
//读者优先-----写者线程
void RP_WriterThread(void *p)
{DWORD m_delay;      //延迟时间DWORD m_persist;    //读文件持续时间int m_ID;           //线程序号m_ID=((ThreadInfo *)(p))->serial;m_delay=(DWORD)(((ThreadInfo *)(p))->delay*INTE_PER_SEC);m_persist=(DWORD)(((ThreadInfo *)(p))->persist*INTE_PER_SEC);Sleep(m_delay);//延迟等待EnterCriticalSection(&cs);for(int i=1;i<m_ID;i++)printf("           ");printf("写者%d写请求\n",m_ID);LeaveCriticalSection(&cs);EnterCriticalSection(&RP_Write);//进入临界区  P(RP_Write);EnterCriticalSection(&cs);for(int l=1;l<m_ID;l++)	//写文件printf("           ");printf("写者%d开始写\n",m_ID);LeaveCriticalSection(&cs);Sleep(m_persist);EnterCriticalSection(&cs);for(int q=1;q<m_ID;q++)	//退出线程printf("           ");printf("写者%d完成写\n",m_ID);LeaveCriticalSection(&cs);LeaveCriticalSection(&RP_Write);  //退出后,离开临界区 V(RP_Write);
}
//写者优先处理函数
void WriterPriority(int num){DWORD n_thread=num;     //线程数目DWORD thread_ID;      //线程IDDWORD wait_for_all;   //等待所有线程结束HANDLE r_Mutex;       //使读者互斥访问readcountHANDLE writerm;       //写互斥 r_Mutex=CreateMutex(NULL,FALSE,"r_Mutex");writerm=CreateMutex(NULL,FALSE,"writerm");InitializeCriticalSection(&pright);InitializeCriticalSection(&w_Mutex);HANDLE h_Thread[MAX_THREAD_NUM];readcount=0;     //初始化readcountwritecount=0;     //初始化writecountprintf("写者优先:(纵坐标为执行顺序)\n");for (int i=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)(WP_ReaderThread),&thread_info[i],0,&thread_ID);else//创建写者线程h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(WP_WriterThread),&thread_info[i],0,&thread_ID);}//等待所有线程结束wait_for_all=WaitForMultipleObjects(n_thread,h_Thread,TRUE,-1);printf("所有操作完成\n");
}//写者优先-----读者线程
void WP_ReaderThread(void *p){	DWORD m_delay;        //延迟时间DWORD m_persist;     //读文件持续时间int m_ID;           //线程序号m_ID=((ThreadInfo *)(p))->serial;m_delay=(DWORD)(((ThreadInfo *)(p))->delay*INTE_PER_SEC);m_persist=(DWORD)(((ThreadInfo *)(p))->persist*INTE_PER_SEC);HANDLE r_Mutex;       //使读者互斥访问readcount    r_Mutex=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"r_Mutex");DWORD wait_for_rmutex;   //等待互斥变量所有权Sleep(m_delay);       //延迟等待EnterCriticalSection(&cs);for(int i=1;i<m_ID;i++)printf("           ");printf("读者%d读请求\n",m_ID);LeaveCriticalSection(&cs);EnterCriticalSection(&pright); //拿到权限 wait_for_rmutex=WaitForSingleObject(r_Mutex,INFINITE);  //控制临界资源readcount if (readcount==0)EnterCriticalSection(&w_Mutex);     //如果这是第一个读者,写者优先进入临界区 P(w_Mutex);readcount++;  //读者数目加1ReleaseMutex(r_Mutex);//V(r_Mutex)LeaveCriticalSection(&pright);//V(pright)EnterCriticalSection(&cs);for(int s=1;s<m_ID;s++)	//读文件printf("           ");printf("读者%d开始读\n",m_ID);LeaveCriticalSection(&cs);Sleep(m_persist);EnterCriticalSection(&cs);for(int r=1;r<m_ID;r++)//退出线程printf("           ");printf("读者%d完成读\n",m_ID);LeaveCriticalSection(&cs);wait_for_rmutex=WaitForSingleObject(r_Mutex,INFINITE);  //P(r_Mutex)readcount--;    //读者数目减1if (readcount==0)LeaveCriticalSection(&w_Mutex);    //如果读者都退出,写者进入临界区V(w_Mutex);ReleaseMutex(r_Mutex);//V(r_Mutex)
}
//写者优先-----写者线程
void WP_WriterThread(void *p){DWORD m_delay;        //延迟时间DWORD m_persist;     //读文件持续时间int m_ID;           //线程序号m_ID=((ThreadInfo *)(p))->serial;m_delay=(DWORD)(((ThreadInfo *)(p))->delay*INTE_PER_SEC);m_persist=(DWORD)(((ThreadInfo *)(p))->persist*INTE_PER_SEC);HANDLE writerm;     writerm=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"writerm");DWORD wait_for_writerm; //等待互斥变量所有权Sleep(m_delay);     //延迟等待EnterCriticalSection(&cs);for(int i=1;i<m_ID;i++)printf("           ");printf("写者%d写请求\n",m_ID);LeaveCriticalSection(&cs);wait_for_writerm=WaitForSingleObject(writerm,INFINITE);//P(writerm)writecount++;   //写者数目加1if (writecount==1)EnterCriticalSection(&pright);//P(pright)ReleaseMutex(writerm);//V(writerm)EnterCriticalSection(&w_Mutex);//P(w_mutex)EnterCriticalSection(&cs);for(int h=1;h<m_ID;h++)	//写文件printf("           ");printf("写者%d开始写\n",m_ID);LeaveCriticalSection(&cs);Sleep(m_persist);EnterCriticalSection(&cs);for(int t=1;t<m_ID;t++)	//退出线程printf("           ");printf("写者%d完成写\n",m_ID);LeaveCriticalSection(&cs);LeaveCriticalSection(&w_Mutex);wait_for_writerm=WaitForSingleObject(writerm,INFINITE);//P(writerm)writecount--;   //写者数目减1if (writecount==0)LeaveCriticalSection(&pright);ReleaseMutex(writerm);//V(writerm)
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/272051.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux排序命令sort笔记

很多时候Linux需要对文本相对比较规范的文本数据进行排序&#xff0c;这时候可以使用Linux系统下的sort命令进行处理。语法格式&#xff1a;sort [-ntkr] filename常用参数&#xff1a;-n 根据数字进行排序-t 指定的分隔符-k 指定分隔符的第几列-r 降序排序用法示例&#xff1a…

《过早退出是一切失败的根源》读后感

在看完周筠老师的文章&#xff1a;过早的退出是一切失败的根源&#xff0c;内心感触颇大。因为年轻&#xff0c;我们总觉得有许许多多的另一个与下一次&#xff0c;我们总是在某个环境里失败或觉得不行时&#xff0c;就会想退出&#xff0c;我们对有风险的事情不愿去尝试&#…

redirect路由配置 vue_Web前端:Vue路由进阶配置

大家好&#xff0c;我来了&#xff0c;本期为大家带来的前端开发知识是”Web前端&#xff1a;Vue路由进阶配置“&#xff0c;有兴趣做前端的朋友&#xff0c;和我一起来看看吧&#xff01;1. 页面打开权限流程页面是否能打开有以下两点判断&#xff1a;1. 判断是否增加登陆的判…

ESP8266模块无限重启崩溃的问题

问题背景&#xff1a; 最近使用ESP8266模块&#xff08;NodeMCU&#xff09;在Arduino环境下进行开发调试时遇到了一个ESP8266模块无限重启崩溃的问题。这个问题不是第一次发生了&#xff0c;很久之前遇到了后面也不知道怎么解决了。 这一次再次碰到了&#xff0c;经过查阅网上…

python格式化输出

格式化输出字符串 格式化输出整数 格式化输出浮点数 输出&

Linux常用内建命令笔记

Linux系统为了便于运维人员对系统的操作&#xff0c;所以内建了很多shell命令。一般来说linux系统的内建命令会比执行外部的shell命令执行更快。因为执行内建命令相当于调用当前shell进程里面的函数&#xff0c;而执行外部命令的话需要出发IO操作还要fork一个单独的进程来执行&…

什么原因接触接触impala的

最近一个项目&#xff0c;关于大数据的改造项目&#xff0c;底层选择Impala还是sparkSQL呢&#xff1f; 最后选择Impala.这样就开启了我的Impala学习之旅。我大部分负责Imapa接口开发工作。 我是控制不住的想整个都了解和学习。所有还在impala控制台各种测试和学习。差不多一两…

asp手机拍照显示_会员动态飞凯材料120吨TFTLCD混合液晶显示项目,建后五年达产...

来源 &#xff1a;全景网10月26日&#xff0c;在飞凯材料可转债发行网上路演会议上&#xff0c;该公司相关人员也对投资者关心的问题进行解答。关于发行8.25亿元可转换债券&#xff0c;飞凯材料表示本次募集资金扣除发行费用后将用于投资以下项目&#xff1a;10000t/a紫外固化光…

python中变量的命名和关键字和变量的命名规则

[False, None, True, and, as, assert, break, class, continue, def, del, elif, else, except, finally, for, from, global, if, import, in, is, lambda, nonlocal, not, or, pass, raise, return, try, while, with, yield]

Linux中Shell数组的笔记

Shell数组的介绍数组算是一种特殊的数据结构&#xff0c;数据项可以成为数组的元素&#xff0c;可以通过数组的索引获取每一个数组的元素值。数组的典型的使用场景是把相同类型的元素汇总在一起。由于Shell变量属于弱类型&#xff0c;所以数组里面的元素并不一定是相同类型。注…

linux中php配置

安装nginxphp好久了&#xff0c;今天意外的搭建好了&#xff0c;分享给大家 &#xff0c;以免以后多走弯路。 nginx已经前面安装好了&#xff0c;现在就开始配置php 安装php 分为两个部分 &#xff1a;一部分是php源码&#xff0c;另外是fastcgi管理进程&#xff1a;php-fpm 庆…

log函数 oracle power_Excel之数学函数SQRT/MOD/EXP/LN/RAND

本部分主要包括ABS函数、SQRT函数、SIGN函数、MOD函数、POWER、EXP函数、LN函数、LOG函数、LOG10函数、RAND函数、RANDBETWEEN函数、PI函数、SIN函数、COS函数、TAN函数、PRODUCT函数、FACT函数、GCD函数、LCM函数、DEGREES函数、RADIANS函数和SUBTOTAL函数共22个。需重点掌握S…

Linux中Shell循环结构for用法笔记

Shell中可以使用for做固定次数循环的处理。常见的for循环用法主要有以下几种&#xff1a;1、带列表的for循环语法结构&#xff1a;for item in (list)docommanddone示例&#xff1a;cat demo1.sh 内容如下&#xff1a;#!/bin/bashnames"小明 小王 小张"for item in n…

斐波那契数列 在实际问题上的变种

我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形&#xff0c;总共有多少种方法1 利用数组结构遍历方法if(target1 || target0)return 1;int [] arr new int [target1];arr[0] 1;arr[1] 1;for(int i2;i<target;i){a…

焊接符号标注图解示例_【干货】焊接图纸符号汇总 ,学习收藏!!

基本坡口符号坡口符号(注&#xff1a;图中“破”应为“坡”)焊接图纸符号标注图解示例焊接符号标注实例及方法在焊接结构图样上&#xff0c;焊接方法可按国家标准GB5185-85的规定用阿拉伯效字表示&#xff0c;标注在指引线的尾部。常用焊接方法代号见表3-9所示。如果是组合焊接…

Linux有关Shell中if用法笔记

shell中的if主要是用于程序的判断逻辑&#xff0c;从而控制脚本的执行逻辑。这和很多编程语言思路上都是一致的。1、if的用法结构如下&#xff1a;if exp;thencommand1;command2;fi示例&#xff1a;#根据输入的学生成绩打印对应的成绩等级&#xff1a;大于90分为优秀&#xff1…

自定义Chrome插件Vimium

自定义快捷键 map e scrollPageUp map w removeTab map s nextTab map a previousTab map q goNext map z restoreTab 默认搜索引擎 https://www.baidu.com/s?wd 添加上一页下一页识别 Previous patterns prev,previous,back,older,<,←,,≪,<<,上一页 Next patterns…

es查询大文本效率_es之路由:进一步提高Elasticsearch的检索效率(适用大规模数据集)...

1&#xff1a;一条数据是如何落地到对应的shard上的当索引一个文档的时候&#xff0c;文档会被存储到一个主分片中。 Elasticsearch 如何知道一个文档应该存放到哪个分片中呢&#xff1f;首先这肯定不会是随机的&#xff0c;否则将来要获取文档的时候我们就不知道从何处寻找了。…