📄 czh.txt
字号:
#include <windows.h>
#include <conio.h>
#include "fstream.h"
//全局变量
int readcount=0; //读者数目
int writecount=0; //写者数目
/*
关键代码段是指一个小代码段,在代码能够执行前,它必须独占对某些共享资源的访问权。
这是让若干行代码能够“以原子操作方式”来使用资源的一种方法。
*/
CRITICAL_SECTION RP_Write; //临界区
CRITICAL_SECTION cs_Write;
CRITICAL_SECTION cs_Read;
struct ThreadInfo //线程信息
{ int Threadhao; //线程序号
char ThreadClass; //线程类别
double ThreadStartTime; //线程开始时间
double ThreadRunTime; //线程读写持续时间
};
void ReaderFun(char* file);//读者优先函数
void R_ReaderThread(void *p);//处理读者优先读者线程
void R_WriterThread(void *p);//处理读者优先写者线程
void WriterFun(char* file);
void W_ReaderThread(void *p);
void W_WriterThread(void *p);
int main()
{
char select;
while (true)
{
cout<<"***************本程序实现读者-写者问题**************\n"<<endl;
cout<<" 1:读者优先"<<endl;
cout<<" 2:写者优先"<<endl;
cout<<" 3:退出"<<endl;
cout<<"\n****************************************************"<<endl;
cout<<"请选择要进行的操作:"<<endl;
do
{
cin>>select;
if(select!='1' && select!='2' && select!='3')
cout<<"你操作有误,请重试!"<<endl;
}while (select!='1' && select!='2' && select!='3');
system("cls");
if (select=='3')
return 0;//退出
else if (select=='1')//调用读者优先
ReaderFun("peizhi.txt");
else if(select=='2')//调用写者优先
WriterFun("peizhi.txt");
cout<<"\n是否还有继续? 1. 继续 2.退出"<<endl;;
do
{
cin>>select;
if(select!='1' && select!='2' )
cout<<"你操作有误,请重试!"<<endl;
}while (select!='1' && select!='2');
if(select=='2')
return 0;// 退出
system("cls");
}
return 0;
}
//读者优先函数
void ReaderFun(char* file)
{
DWORD n_thread=0; //线程数初值为0
DWORD thread_ID; //线程ID
DWORD wait_for_all; //等待所有线程结束
//临界资源
HANDLE h_Mutex;
//互斥对象(h_Mutex)确保线程拥有对单个资源的互斥访问权
h_Mutex=CreateMutex(NULL,FALSE,"mutex_for_readcount");
/*创建互斥对象,
NULL表示创建带有默认安全性的内核对象
FALSE表示该互斥对象没有被任何线程所拥有
mutex_for_readcount是为内核对象赋予名字。
*/
HANDLE h_Thread[64]; //线程对象数组,最大64
ThreadInfo thread_info[64];
readcount=0;
InitializeCriticalSection(&RP_Write); //初始化临界区
ifstream inFile;
inFile.open(file);
cout<<"读者优先:\n"<<endl;
while (inFile)
{
//读入每一个读者、写者的信息
inFile>>thread_info[n_thread].Threadhao>>thread_info[n_thread].ThreadClass
>>thread_info[n_thread].ThreadStartTime>>thread_info[n_thread].ThreadRunTime;
if (-1 == inFile.get())
break;
n_thread++;//线程数加一
}
for (int i=0;i<(int)(n_thread);i++)
{
if (thread_info[i].ThreadClass=='r')
//创建读者线程
h_Thread[i]=CreateThread(NULL,0,\
(LPTHREAD_START_ROUTINE)(R_ReaderThread),\
&thread_info[i],0,&thread_ID);
/*
NULL表示创建带有默认安全性的内核对象
0表示CreateThread就保留一个区域,并且将链接程序
嵌入. EXE文件的/ STACK链接程序开关信息指明
的存储器容量分配给线程堆栈。
(LPTHREAD_START_ROUTINE)(R_ReaderThread)表示新线程执行的线程函数的地址
&thread_info[i]表示在线程启动执行时将该参数传递给线程函数。
0表示读者线程创建后可以立即进行调度
&thread_ID表示CreateThread使用这个地址来存放系统分配
给新读者线程的I D
*/
else
//创建写者线程
h_Thread[i]=CreateThread(NULL,0,\
(LPTHREAD_START_ROUTINE)(R_WriterThread),\
&thread_info[i],0,&thread_ID);
}
wait_for_all=WaitForMultipleObjects(n_thread,h_Thread,TRUE,-1);
/*
等待函数可使线程自愿进入等待状态,直到一个特定的内核对象变为已通知状态为止
n_thread表示线程数量。
h_Thread是指向线程对象句柄的数组的指针。
ture表示:在所有线程对象变为已通知状态之前,该函数将不允许调用线程运行
参数 -1 告诉系统,调用线程愿意永远等待下去(无限时间量),直到该进程终止运行。
*/
cout<<"所有的读者和写者线程完成操作."<<endl;
}
//读者优先-----读者线程
void R_ReaderThread(void *p)
{
//互斥变量
HANDLE h_Mutex;
h_Mutex=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex_for_readcount");
/*
获得它自己进程与现有互斥对象相关的句柄:
*/
DWORD wait_for_mutex; //等待互斥变量所有权
DWORD m_delay; //延迟时间
DWORD m_ThreadRunTime; //读文件持续时间
int m_Threadhao; //线程序号
m_Threadhao=((ThreadInfo *)(p))->Threadhao;
m_delay=(DWORD)(((ThreadInfo *)(p))->ThreadStartTime*100);
m_ThreadRunTime=(DWORD)(((ThreadInfo *)(p))->ThreadRunTime*100);
Sleep(m_delay); //延迟等待
cout<<"读者线程 "<<m_Threadhao<<" 发出读请求."<<endl;
wait_for_mutex=WaitForSingleObject(h_Mutex,-1); //等待互斥信号,保证对readcount的访问、
//修改互斥
readcount++; //读者数目加一
if (readcount==1)
EnterCriticalSection(&RP_Write);//禁止写者进入
ReleaseMutex(h_Mutex);//释放互斥对象,允许下个读者继续读:
//读文件
cout<<"读者线程 "<<m_Threadhao<<" 开始读文件."<<endl;
Sleep(m_ThreadRunTime);
//退出线程
cout<<"读者线程 "<<m_Threadhao<<" 完成读文件."<<endl;
wait_for_mutex=WaitForSingleObject(h_Mutex,-1); //等待互斥信号,保证对readcount的访问、修改互斥
readcount--; //读者数目减少
if (readcount==0)
LeaveCriticalSection(&RP_Write); //如果所有读者读完,唤醒写者
ReleaseMutex(h_Mutex);//释放互斥信号
}
//读者优先-----写者线程
void R_WriterThread(void *p)
{
DWORD m_delay; //延迟时间
DWORD m_ThreadRunTime; //读文件持续时间
int m_Threadhao; //线程序号
//从参数中获得信息
m_Threadhao=((ThreadInfo *)(p))->Threadhao;
m_delay=(DWORD)(((ThreadInfo *)(p))->ThreadStartTime*100);
m_ThreadRunTime=(DWORD)(((ThreadInfo *)(p))->ThreadRunTime*100);
Sleep(m_delay); //延迟等待
cout<<"写者线程 "<<m_Threadhao<<" 发出写请求."<<endl;
EnterCriticalSection(&RP_Write);//禁止下一位写者进入
//写文件
cout<<"写者线程 "<<m_Threadhao<<" 开始写文件."<<endl;
Sleep(m_ThreadRunTime);
//退出线程
cout<<"写者线程 "<<m_Threadhao<<" 完成写文件."<<endl;
LeaveCriticalSection(&RP_Write); //如果所有读者读完,唤醒写者
}
//写者优先处理函数
void WriterFun(char* file)
{
DWORD n_thread=0; //线程数目
DWORD thread_ID; //线程ID
DWORD wait_for_all; //等待所有线程结束
//互斥对象
HANDLE h_Mutex1, h_Mutex2, h_Mutex3;
h_Mutex1 = CreateMutex(NULL, FALSE, "mutex_for_writecount");
h_Mutex2 = CreateMutex(NULL, FALSE, "mutex_for_readcount");
h_Mutex3 = CreateMutex(NULL, FALSE, "mutex_for_read");
//线程对象数组
HANDLE h_Thread[64];
ThreadInfo thread_info[64];
readcount=0; //初始化readcount
InitializeCriticalSection(&cs_Write); //初始化临界区
InitializeCriticalSection(&cs_Read);
ifstream inFile;
inFile.open(file); //打开文件
cout<<"写者优先:\n"<<endl;
while (inFile)
{
//读入每一个读者、写者的信息
inFile>>thread_info[n_thread].Threadhao>>thread_info[n_thread].ThreadClass
>>thread_info[n_thread].ThreadStartTime>>thread_info[n_thread].ThreadRunTime;
if(-1 == inFile.get())
break;
n_thread++;//线程数加一
}
for (int i=0;i<(int)(n_thread);i++)
{
if (thread_info[i].ThreadClass=='r')
//创建读者线程
h_Thread[i]=CreateThread(NULL,0,\
(LPTHREAD_START_ROUTINE)(W_ReaderThread),\
&thread_info[i],0,&thread_ID);
else
//创建写者线程
h_Thread[i]=CreateThread(NULL,0,\
(LPTHREAD_START_ROUTINE)(W_WriterThread),\
&thread_info[i],0,&thread_ID);
}
//等待所有线程结束
wait_for_all=WaitForMultipleObjects(n_thread,h_Thread,TRUE,-1);
cout<<"所有的读者和写者线程完成操作."<<endl;
}
//写者优先-----写者线程
void W_WriterThread(void *p)
{
//互斥变量
HANDLE h_Mutex1;
h_Mutex1 = OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex_for_writecount");
DWORD wait_for_mutex; //等待互斥变量所有权
DWORD m_delay; //延迟时间
DWORD m_ThreadRunTime; //读文件持时续间
int m_Threadhao; //线程序号
m_Threadhao=((ThreadInfo *)(p))->Threadhao;
m_delay=(DWORD)(((ThreadInfo *)(p))->ThreadStartTime*100);//每秒时钟中断100次
m_ThreadRunTime=(DWORD)(((ThreadInfo *)(p))->ThreadRunTime*100);//每秒时钟中断100次
Sleep(m_delay);
cout<<"写者线程 "<<m_Threadhao<<" 发出写请求."<<endl;
wait_for_mutex=WaitForSingleObject(h_Mutex1,-1);
writecount++;
if (writecount==1)
EnterCriticalSection(&cs_Read);
ReleaseMutex(h_Mutex1);
EnterCriticalSection(&cs_Write);
cout<<"写者线程 "<<m_Threadhao<<" 开始写文件."<<endl;
Sleep(m_ThreadRunTime);
cout<<"写者线程 "<<m_Threadhao<<" 完成写文件."<<endl;
LeaveCriticalSection(&cs_Write);
wait_for_mutex=WaitForSingleObject(h_Mutex1,-1);
writecount--;
if(writecount == 0)
LeaveCriticalSection(&cs_Read);
ReleaseMutex(h_Mutex1);
}
//写者优先-----读者线程
void W_ReaderThread(void *p)
{
HANDLE h_Mutex2, h_Mutex3;
h_Mutex2 = OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex_for_readcount");
h_Mutex3 = OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex_for_read");
DWORD wait_for_mutex, wait_for_mutex1; //等待互斥变量所有权
DWORD m_delay; //延迟时间
DWORD m_ThreadRunTime; //读文件持续时间
int m_Threadhao; //线程序号
m_Threadhao=((ThreadInfo *)(p))->Threadhao;
m_delay=(DWORD)(((ThreadInfo *)(p))->ThreadStartTime*100);
m_ThreadRunTime=(DWORD)(((ThreadInfo *)(p))->ThreadRunTime*100);
Sleep(m_delay);
cout<<"读者线程 "<<m_Threadhao<<" 发出读请求."<<endl;
wait_for_mutex1=WaitForSingleObject(h_Mutex3,-1);
EnterCriticalSection(&cs_Read);
LeaveCriticalSection(&cs_Read);
ReleaseMutex(h_Mutex3);
wait_for_mutex=WaitForSingleObject(h_Mutex2,-1);
readcount++;
if (readcount == 1)
EnterCriticalSection(&cs_Write);
ReleaseMutex(h_Mutex2);
cout<<"读者线程 "<<m_Threadhao<<" 开始读文件."<<endl;
Sleep(m_ThreadRunTime);
cout<<"读者线程 "<<m_Threadhao<<" 完成读文件."<<endl;
wait_for_mutex=WaitForSingleObject(h_Mutex2,-1);
readcount--;
if (readcount == 0)
LeaveCriticalSection(&cs_Write);
ReleaseMutex(h_Mutex2);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -