#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <windows.h>
#include <io.h>
#include <conio.h>
#include <stdlib.h>
#include <fstream>
using namespace std;
#define READER 'R' //读者
#define WRITER 'W' //写者
#define DELAY_TIME 700 //最基本的延迟时间,其他都为他的倍数
#define MAX_THREAD_NUM 64 //最大线程数
int readercount = 0; //读者数量
int writercount = 0; //写者数量
//临界区
CRITICAL_SECTION RP_Write;
CRITICAL_SECTION WP_Write;
CRITICAL_SECTION WP_Read;
//线程结构体
struct Thread{
int serial; //线程序号
char entity; //判断是读者线程还是写者线程
double delay; //线程延迟
double persist; //线程写操作持续时间
};
//读者优先 读者进程
void RP_ReaderThread(void *p){
//互斥变量
HANDLE h_Mutex;
h_Mutex = OpenMutex(MUTEX_ALL_ACCESS,false,"mutex");
DWORD m_delay = (DWORD)(((Thread*)(p))->delay*DELAY_TIME); //延迟时间
DWORD m_persist = (DWORD)(((Thread*)(p))->persist*DELAY_TIME); //读文件持续时间 用来模拟线程活动
int m_serial = ((Thread*)(p))->serial; //线程号
Sleep(m_delay);
cout<<"读者线程 "<<m_serial<<" 发送读请求"<<endl;
WaitForSingleObject(h_Mutex,-1);//修改互斥信号量
readercount++;//读者增加
if(readercount==1){
//第一个读者等待资源
EnterCriticalSection(&RP_Write);
}
ReleaseMutex(h_Mutex);
//读文件
cout<<"读者线程 "<<m_serial<<" 开始读文件。"<<endl;
Sleep(m_persist);
//退出线程
cout<<"读者线程 "<<m_serial<<" 已读完文件。"<<endl;
//改变互斥信号量
WaitForSingleObject(h_Mutex,-1);
readercount--;
if(readercount==0){
//如果所有读者读完,唤醒写者
LeaveCriticalSection(&RP_Write);
}
ReleaseMutex(h_Mutex);//释放信号量
}
//读者优先 写者进程
void RP_WriterThread(void *p){
DWORD m_delay= (((Thread*)(p))->delay*DELAY_TIME);; //延迟时间
DWORD m_persist= (((Thread*)(p))->persist*DELAY_TIME);; //读文件持续时间 用来模拟线程活动
int m_serial=((Thread*)(p))->serial;; //线程号
Sleep(m_delay);
cout<<"写者线程 "<<m_serial<<" 发送写请求。"<<endl;
//等待资源分配给自己
EnterCriticalSection(&RP_Write);
cout<<"写者线程 "<<m_serial<<" 开始写文件。"<<endl;
Sleep(m_persist);
cout<<"写者线程 "<<m_serial<<" 已写完文件。"<<endl;
LeaveCriticalSection(&RP_Write);//释放资源
}
//读者优先处理函数
void ReaderPriority(char *file){
DWORD n_thread=0; //线程数目
DWORD thread_ID; //线程ID
//信号量
HANDLE h_Mutex;
h_Mutex=CreateMutex(NULL,false,"mutex");
//存取线程的数组
HANDLE h_Thread[MAX_THREAD_NUM];
Thread threads[MAX_THREAD_NUM];
readercount = 0;//初始化读者数量
InitializeCriticalSection(&RP_Write);//初始化临界区
//打开文件
ifstream inFile;
inFile.open(file);
cout<<"读者优先:"<<endl;
cout<<endl;
//获取文件内容
while(inFile){
inFile>>threads[n_thread].serial;
inFile>>threads[n_thread].entity;
inFile>>threads[n_thread].delay;
inFile>>threads[n_thread++].persist;
inFile.get();
}
for(int i=0;i<(int)(n_thread);i++){
if(threads[i].entity==READER||threads[i].entity=='r')
{
//创建读者线程
h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(RP_ReaderThread),&threads[i],0,&thread_ID);
}
else
//创建写者线程
h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(RP_WriterThread),&threads[i],0,&thread_ID);
}
//等待所有线程结束
WaitForMultipleObjects(n_thread,h_Thread,true,-1);
cout<<"所有的读者和写者完成各自操作。"<<endl;
}
//写者优先 读者进程
void WP_ReaderThread(void *p)
{
//互斥变量
HANDLE h_Mutex1;
h_Mutex1 = OpenMutex(MUTEX_ALL_ACCESS,false,"mutex1");
HANDLE h_Mutex2; //互斥信号量 保证对readercount的访问和修改互斥
h_Mutex2 = OpenMutex(MUTEX_ALL_ACCESS,false,"mutex2");
DWORD m_delay = (DWORD)(((Thread*)(p))->delay*DELAY_TIME);
DWORD m_persist = (DWORD)(((Thread*)(p))->persist*DELAY_TIME);
int m_serial = ((Thread*)(p))->serial;
Sleep(m_delay);//延迟等待
cout<<"读者线程 "<<m_serial<<" 发送读请求"<<endl;
WaitForSingleObject(h_Mutex1,-1);
//读者进入临界区
EnterCriticalSection(&WP_Read);
WaitForSingleObject(h_Mutex2,-1);
readercount++;//读者的数目增加
if(readercount==1){
//第一个读者等待资源,等待读者写完
EnterCriticalSection(&WP_Write);
}
ReleaseMutex(h_Mutex2); //释放信号量
//使其他读者进入
LeaveCriticalSection(&WP_Read);
ReleaseMutex(h_Mutex1);
//读文件
cout<<"读者线程 "<<m_serial<<" 开始读文件。"<<endl;
Sleep(m_persist);
//退出线程
cout<<"读者线程 "<<m_serial<<" 已读完文件。"<<endl;
//修改互斥信号量
WaitForSingleObject(h_Mutex2,-1);
readercount--;
if(readercount==0){
//如果所有读者读完,唤醒写者
LeaveCriticalSection(&WP_Write);
}
ReleaseMutex(h_Mutex2);//释放信号量
}
//写者优先 写者进程
void WP_WriterThread(void *p){
DWORD m_delay;
DWORD m_persist;
int m_serial;
//互斥信号量
HANDLE h_Mutex3;
h_Mutex3 = OpenMutex(MUTEX_ALL_ACCESS,false,"mutex3");
//从参数中获取信息
m_serial=((Thread*)(p))->serial;
m_delay = (((Thread*)(p))->delay*DELAY_TIME);
m_persist = (((Thread*)(p))->persist*DELAY_TIME);
Sleep(m_delay);
cout<<"写者线程 "<<m_serial<<" 发送写请求。"<<endl;
WaitForSingleObject(h_Mutex3,-1);//修改互斥信号量
writercount++;//写者数目增加
if(writercount==1){
//第一个写者申请并等待资源
EnterCriticalSection(&WP_Read);
}
ReleaseMutex(h_Mutex3);//释放信号量
EnterCriticalSection(&WP_Write); //等待资源分配给自己
cout<<"写者线程 "<<m_serial<<" 开始写文件。"<<endl;
Sleep(m_persist);
cout<<"写者线程 "<<m_serial<<" 已写完文件。"<<endl;
//唤醒其他等待的写者
LeaveCriticalSection(&WP_Write);
WaitForSingleObject(h_Mutex3,-1);//修改互斥信号量
writercount--;
if(writercount==0){
//写者数目为0,唤醒读者
LeaveCriticalSection(&WP_Read);
}
ReleaseMutex(h_Mutex3);
}
//写者优先处理函数
void WriterPriority(char *file){
DWORD n_thread=0; //线程数目
DWORD thread_ID;//线程ID
//创建相应临界区
HANDLE h_Mutex1;
h_Mutex1=CreateMutex(NULL,false,"mutex1");
HANDLE h_Mutex2;
h_Mutex2=CreateMutex(NULL,false,"mutex2");
HANDLE h_Mutex3;
h_Mutex3=CreateMutex(NULL,false,"mutex3");
//创建线程数组
HANDLE h_Thread[MAX_THREAD_NUM];
Thread threads[MAX_THREAD_NUM];
//初始化计数器和临界区
readercount = 0;
writercount = 0;
InitializeCriticalSection(&WP_Write);
InitializeCriticalSection(&WP_Read);
//打开文件
ifstream inFile;
inFile.open(file);
cout<<"写者优先:"<<endl;
cout<<endl;
//获取文件内容
while(inFile){
inFile>>threads[n_thread].serial;
inFile>>threads[n_thread].entity;
inFile>>threads[n_thread].delay;
inFile>>threads[n_thread++].persist;
inFile.get();
}
for(int i=0;i<(int)(n_thread);i++){
if(threads[i].entity==READER||threads[i].entity=='r')
{
//创建读者线程
h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(RP_ReaderThread),&threads[i],0,&thread_ID);
}
else
//创建写者线程
h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(RP_WriterThread),&threads[i],0,&thread_ID);
}
WaitForMultipleObjects(n_thread,h_Thread,true,-1);
cout<<"所有的读者和写者完成各自操作。"<<endl;
}
int main(){
int num;
int cnt = 0;
while(1){
cout<<"************************************"<<endl;
cout<<endl;
cout<<"| 1.读者优先 |"<<endl;
cout<<"| 2.写者优先 |"<<endl;
cout<<"| 3.退出程序 |"<<endl;
cout<<endl;
cout<<"************************************"<<endl;
start:
cout<<"请输入你所要进行的选择:"<<endl;
cin>>num;
if(num<1||num>3)
{
cout<<"输入无效,请重新输入"<<endl;
goto start;
}
else if(num==1){
ReaderPriority("thread.txt");
}
else if(num==2){
WriterPriority("thread.txt");
}
else if(num==3)
{
exit(0);
}
system("pause");
system("cls");
}
system("pause");
return 0;
}
thread中的内容为
1 R 3 5
2 W 4 5
3 R 5 2
4 R 6 5
5 W 5.1 3
6 W 3 5
7 W 16 5
8 R 5 2
9 W 6 5
10 R 4 3
11 R 17 7