讀者寫者問題

河北科技大學操作系統課程設計——讀者寫者問題

#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.pswp.cn/news/272051.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/272051.shtml
英文地址,請注明出處:http://en.pswp.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;否則將來要獲取文檔的時候我們就不知道從何處尋找了。…