📄 os2.cpp
字号:
#include <stdio.h>
#include <windows.h>
#include <fstream.h>
#define INTE_PER_SEC 1000 //每秒时钟中断的数目
#define MAX_THREAD_NUM 10 //最大线程数
int readcount=0; //读者数目
int writecount=0; //写者数目
CRITICAL_SECTION RP_Write; //临界资源
CRITICAL_SECTION cs_Write;
CRITICAL_SECTION cs_Read;
struct ThreadInfo
{
int serial; //线程序号
char entity; //线程类别
double delay; //线程延迟时间
double persist; //线程读写操作时间
};
void RP_ReaderThread(void *p) // 读者优先——读者线程信息
{
HANDLE h_Mutex; //互斥变量
h_Mutex=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex_for_readcount"); //h_mutex来实现对全局变量readcount修改时的互斥,
//打开这对互斥对象,
//FALSE表示打开此对象的线程不同时具有该互斥对象的所有权
//mutex_for_readcount与已存在的有名互斥对象名相匹配,所以用MUTEX_ALL_ACCESS权限访问已存在的对象
DWORD wait_for_mutex; //等待互斥变量所有权,定义为双字类型
DWORD m_delay; //延迟时间没,定义为双字类型
DWORD m_persist; //读文件持续时间,定义为双字类型
int m_serial; //线程序号
// 从参数中获得信息
m_serial=((ThreadInfo*)(p))->serial ;
m_delay=(DWORD)(((ThreadInfo*)(p))->delay *INTE_PER_SEC);
m_persist=(DWORD)(((ThreadInfo*)(p))->persist *INTE_PER_SEC);
Sleep(m_delay); //延迟等待,即屏幕上会有时间间隔地显示,象征表明这段时间正在申请
printf("\n读者线程 %d 申请读操作.\n",m_serial);
wait_for_mutex=WaitForSingleObject(h_Mutex,-1);//等待互斥信号,保证对ReadCount 的访问,修改互斥
readcount++; //经过上面,已有读者到来,读者数目增加
if(readcount==1) //第一个读者,等待资源
{
EnterCriticalSection(&RP_Write); //指定临界区对象的所有权,当前被调用线程被赋予所有权
}
ReleaseMutex(h_Mutex); //释放互斥信号
/////////////////////////读文件
printf("\n读者线程 %d 开始读操作.\n",m_serial);
Sleep(m_persist); //线程持续时间,即屏幕上会有时间间隔地显示,象征表明这段时间正在读操作
//////////////////////退出线程
printf("\n读者线程 %d 完成读操作.\n",m_serial);
wait_for_mutex=WaitForSingleObject(h_Mutex,-1);//等待互斥信号,保证对ReadCount的访问,修改互斥
readcount--;//经过上面,一个读操作完成,读者数目减少
if(readcount==0)//如果所有的读者读完,唤醒写者
{
LeaveCriticalSection(&RP_Write); //释放指定临界区对象的所有权
}
ReleaseMutex(h_Mutex); //释放互斥信号,与上四行的wait_for_mutex相对应
}
void RP_WriterThread(void *p) // 读者优先——写者线程信息
{
DWORD m_delay; //延迟时间 ,定义为双字类型
DWORD m_persist; //写文件持续时间 ,定义为双字类型
int m_serial; //线程序号
// 从参数中获得信息
m_serial=((ThreadInfo*)(p))->serial ;
m_delay=(DWORD)(((ThreadInfo*)(p))->delay *INTE_PER_SEC);
m_persist=(DWORD)(((ThreadInfo*)(p))->persist *INTE_PER_SEC);
Sleep(m_delay);
printf("\n写者线程 %d 申请写操作.\n",m_serial);
//等待资源
EnterCriticalSection(&RP_Write);
//写文件
printf("\n写者线程 %d 开始写操作.\n",m_serial);
Sleep(m_persist);
//退出线程
printf("\n写者线程 %d 完成写操作.\n",m_serial);
//释放资源
LeaveCriticalSection(&RP_Write);
}
void ReaderPriority(char *file)//读者优先处理函数
{
DWORD n_thread=0; //线程数目 ,定义为双字类型
DWORD thread_ID; //线程标号,定义为双字类型
//DWORD wait_for_all; //等待所有线程结束,定义为双字类型
HANDLE h_Mutex; //互斥对象
h_Mutex=CreateMutex(NULL,FALSE,"mutex_for_readcount");//mutex来实现对全局变量readcount修改时的互斥,
//创建这对互斥对象,
//FALSE表示创建此对象的线程不同时具有该互斥对象的所有权
HANDLE h_Thread[MAX_THREAD_NUM];//要创建的线程对象的数组
ThreadInfo thread_info[MAX_THREAD_NUM];//线程结构体数组,最大线程数为10,用于存储从文本文件中读入的
readcount=0;
InitializeCriticalSection(&RP_Write); //初始化临界区对象
ifstream ReadFile;
ReadFile.open (file); //打开只读文件
printf("读者优先:\n");
while(ReadFile)
{
//读入每一个读者,写者的信息,存入thread_info线程结构体数组中
ReadFile>>thread_info[n_thread].serial;
ReadFile>>thread_info[n_thread].entity;
ReadFile>>thread_info[n_thread].delay;
ReadFile>>thread_info[n_thread].persist;
n_thread++;
ReadFile.get();
}
for(int i=0;i<(int)(n_thread);i++)
{
if(thread_info[i].entity=='R'||thread_info[i].entity =='r')
{
//创建读者进程
h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(RP_ReaderThread),&thread_info[i],0,&thread_ID);//句柄不能被继承,即参数1设为NULL
}
if(thread_info[i].entity=='W'||thread_info[i].entity =='w')
{
//创建写线程
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 WP_ReaderThread(void *p)//写者优先---读者线程信息
{
HANDLE h_Mutex1; //互斥变量
h_Mutex1=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex1");//h_mutex1来实现对全局变量readcount修改时的互斥,
HANDLE h_Mutex2;
h_Mutex2=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex2");
DWORD wait_for_mutex1; //等待互斥变量所有权,定义为双字类型
DWORD wait_for_mutex2;
DWORD m_delay; //延迟时间,定义为双字类型
DWORD m_persist; //读文件持续时间,定义为双字类型
int m_serial; //线程的序号
//从参数中得到信息
m_serial=((ThreadInfo*)(p))->serial ;
m_delay=(DWORD)(((ThreadInfo*)(p))->delay *INTE_PER_SEC);
m_persist=(DWORD)(((ThreadInfo*)(p))->persist *INTE_PER_SEC);
Sleep(m_delay); //延迟等待,即屏幕上会有时间间隔地显示,象征表明这段时间正在申请
printf("\n读者线程 %d 申请读操作.\n",m_serial);
wait_for_mutex1=WaitForSingleObject(h_Mutex1,-1);
//读者进去临界区
EnterCriticalSection(&cs_Read);
//阻塞互斥对象Mutex2,保证对readcount的访问和修改互斥
wait_for_mutex2=WaitForSingleObject(h_Mutex2,-1);
//修改读者的数目
readcount++;
if(readcount==1)
{
// 如果是第1个读者,等待写者写完
EnterCriticalSection(&cs_Write);
}
ReleaseMutex(h_Mutex2);// 释放互斥信号 Mutex2
//让其他读者进去临界区
LeaveCriticalSection(&cs_Read);
ReleaseMutex(h_Mutex1);
//读文件
printf("\n读者线程 %d 开始读操作.\n",m_serial);
Sleep(m_persist); //线程持续时间,即屏幕上会有时间间隔地显示,象征表明这段时间正在读操作
//退出线程
printf("\n读者线程 %d 完成读操作.\n",m_serial);
//阻塞互斥对象Mutex2,保证对readcount的访问,修改互斥
wait_for_mutex2=WaitForSingleObject(h_Mutex2,-1);
readcount--;
if(readcount==0)
{
//最后一个读者,唤醒写者
LeaveCriticalSection(&cs_Write);
}
ReleaseMutex(h_Mutex2); //释放互斥信号
}
void WP_WriterThread(void *p) //写者优先---写者线程信息
{
DWORD wait_for_mutex3; //互斥变量,定义为双字类型
DWORD m_delay; //延迟时间,定义为双字类型
DWORD m_persist; //读文件持续时间 ,定义为双字类型
int m_serial; //线程序号
HANDLE h_Mutex3;
h_Mutex3=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex3");//h_mutex3来实现对全局变量writecount修改时的互斥,
//打开这对互斥对象,
//FALSE表示打开此对象的线程不同时具有该互斥对象的所有权
//mutex_for_readcount与已存在的有名互斥对象名相匹配,所以用MUTEX_ALL_ACCESS权限访问已存在的对象
//从参数中获得信息
m_serial=((ThreadInfo*)(p))->serial ;
m_delay=(DWORD)(((ThreadInfo*)(p))->delay *INTE_PER_SEC);
m_persist=(DWORD)(((ThreadInfo*)(p))->persist *INTE_PER_SEC);
Sleep(m_delay); //延迟等待,即屏幕上会有时间间隔地显示,象征表明这段时间正在申请
printf("\n写者线程%d 申请写操作.\n",m_serial);
wait_for_mutex3=WaitForSingleObject(h_Mutex3,-1);
writecount++; //经过上面,已有写者到来,所以修改写者数目
if(writecount==1)//第一个写者,等待资源
{
EnterCriticalSection(&cs_Read);//指定临界区对象的所有权,当前被调用线程被赋予所有权
}
ReleaseMutex(h_Mutex3); //释放互斥信号h_Mutex3
EnterCriticalSection(&cs_Write);
printf("\n写者线程 %d 开始写操作.\n",m_serial);
Sleep(m_persist);//线程持续时间,即屏幕上会有时间间隔地显示,象征表明这段时间正在写操作
printf("\n写者线程%d 完成写操作.\n",m_serial);
LeaveCriticalSection(&cs_Write);
wait_for_mutex3=WaitForSingleObject(h_Mutex3,-1); //等待互斥信号,保证对writecount的访问,修改互斥
writecount--;
if(writecount==0)
{
LeaveCriticalSection(&cs_Read);
}
ReleaseMutex(h_Mutex3);
}
void WriterPriority(char * file)//写者优先处理函数
{
DWORD n_thread=0;
DWORD thread_ID;
//DWORD wait_for_all;
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];
ThreadInfo thread_info[MAX_THREAD_NUM];
readcount=0;
writecount=0;
InitializeCriticalSection(&cs_Write);
InitializeCriticalSection(&cs_Read);
ifstream ReadFile;
ReadFile.open (file);
printf("写者优先:\n");
while(ReadFile)
{
ReadFile>>thread_info[n_thread].serial;
ReadFile>>thread_info[n_thread].entity;
ReadFile>>thread_info[n_thread].delay;
ReadFile>>thread_info[n_thread].persist;
n_thread++;
ReadFile.get();
}
for(int i=0;i<(int)(n_thread);i++)
{
if(thread_info[i].entity=='R'||thread_info[i].entity =='r')
{
//创建读者进程
h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(WP_ReaderThread),&thread_info[i],0,&thread_ID);
}
if(thread_info[i].entity=='W'||thread_info[i].entity =='w')
{
//创建写线程
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("All reader and writer have finished operating.\n");
}
void main()
{
int select;
while(1)
{
printf("*************************************\n");
printf(" 1.读者优先\n");
printf(" 2.写者优先\n");
printf(" 0.退出\n");
printf("*************************************\n");
printf("请选择: ");
scanf("%d",&select);
switch(select)
{
case 1:
ReaderPriority("thread.txt");
Sleep(20000);
printf("\n所有读写操作均已完成.\n");
break;
case 2:
WriterPriority("thread.txt");
Sleep(20000);
printf("\n所有读写操作均已完成.\n");
break;
case 0:
exit(0);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -