问题分析:
读者优先:
- 读者进程执行:
- 无其他读者写者, 直接执行
- 有写者等, 但其他读者在读, 直接读
- 有写者写, 等待
- 写者进程执行:
- 无其他读写者, 直接执行
- 有其他读写者, 等待
写者优先:
- 读者进程执行:
- 如果此时没有写者等待, 直接执行
- 如果有写者等待, 那么等待
- 写者进程执行:
- 如果没有其他写者, 那么执行
- 如果有其他读写者, 那么等待
伪代码:
读者优先:
读者R:
Wait(rmutex);
rcount++;
if(rcount == 1)
Wait(wmutex);
Signal(rmutex);
Read_Action();
Wait(rmutex);
rcount--;
if(rcount == 0)
Signal(wmutex);
Signal(rmutex);
写者W:
Wait(wmutex);
Write_Action();
Signal(wmutex);
写者优先:
int wcount=0,rcount=0;
semaphore w=1,r=1,x=1;
读者R:
reader(){
P(r);
P(x);
rcount++;
if(rcount==1)
P(w);
V(x);
V(r);
//Read()
P(x);
rcount--;
if(rcount==0)
V(w);
V(x);
}
写者W:
writer(){
P(x);
wcount++;
if(wcount==1)
P(r);
V(x);
P(w);
//Write()
V(w);
P(x);
wcount--;
if(wcount==0)
V(r);
V(x);
}
源码C++实现:
#include <iostream>
#include <string.h>
#include <memory.h>
#include <windows.h>
#include <conio.h>
#include <stdlib.h>
#include <fstream>
#define MAX_THREAD_NUM 64 //最大线程数
#define INTE_PER_SEC 1000 //每秒时钟中断的数目
#define MAX_FILE_NUM 32 //最大文件数目数
#define MAX_STR_LEN 32 //字符串的长度
using namespace std;
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) //P:读者线程信息
{
//互斥变量
HANDLE h_Mutex;
h_Mutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "mutex_for_readcount");
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); //延迟等待
cout << "Reader thread " << m_serial << " sents the reading require !" << endl;
//等待互斥信号,保证对 ReadCount 的访问,修改互斥
wait_for_mutex = WaitForSingleObject(h_Mutex, -1);
//读者数目增加
readcount++;
if (readcount == 1)
{
//第一个读者,等待资源
EnterCriticalSection(&RP_Write);
}
ReleaseMutex(h_Mutex); //释放互斥信
//读文件
cout << "Reader thread " << m_serial << " begins to read file !" << endl;
Sleep(m_persist);
//退出线程
cout << "Reader thread " << m_serial << " finished reading file !" << endl;
//等待互斥信号,保证对 ReadCount 的访问,修改互斥
wait_for_mutex = WaitForSingleObject(h_Mutex, -1);
//读者数目减少
readcount--;
if (readcount == 0)
{
//如果所有的读者读完,唤醒写者
LeaveCriticalSection(&RP_Write);
}
ReleaseMutex(h_Mutex); //释放互斥信号
}
//P:写者线程信息
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);
cout << "Writer thread " << m_serial << " sents the writing require !" << endl;
//等待资源
EnterCriticalSection(&RP_Write);
//写文件
cout << "Writer thread " << m_serial << " begins to write file !" << endl;
Sleep(m_persist);
//退出线程
cout << "Writer thread " << m_serial << " finished writing file !" << endl;
//释放资源
LeaveCriticalSection(&RP_Write);
}
//读者优先处理函数
void ReaderPriority(const char *fileName)
{
DWORD n_thread = 0; //线程数目
DWORD thread_ID; //线程 ID
DWORD wait_for_all; //等待所有线程结束
//互斥对象
HANDLE h_Mutex;
h_Mutex = CreateMutex(NULL, FALSE, "mutex_for_readcount");
//线程对象的数组
HANDLE h_Thread[MAX_THREAD_NUM];
ThreadInfo thread_info[MAX_THREAD_NUM];
readcount = 0; //初始化 readcount
InitializeCriticalSection(&RP_Write); //初始化临界区
ifstream inFile;
inFile.open(fileName);
if (!inFile)
{
cout << "文件打开失败!" << endl;
}
cout << "读者优先:" << endl;
while (inFile)
{
//读入每一个读者,写者的信息
inFile >> thread_info[n_thread].serial;
inFile >> thread_info[n_thread].entity;
inFile >> thread_info[n_thread].delay;
inFile >> thread_info[n_thread++].persist;
inFile.get();
}
for (int i = 0; i < (int)(n_thread); i++)
{
if (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);
cout << "All reader and writer have finished operating !" << endl;
}
//写者优先---读者线程
//P:读者线程信息
void WP_ReaderThread(void *p)
{
HANDLE print;
print = CreateMutex(NULL, FALSE, LPCTSTR("mutex_for_print"));
//互斥变量
HANDLE h_Mutex1;
h_Mutex1 = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "mutex1");
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); //延迟等待
DWORD wait_to_print = WaitForSingleObject(print, -1);
cout << "Reader thread " << m_serial << " sents the reading require !" << endl;
ReleaseMutex(print);
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);
//读文件
wait_to_print = WaitForSingleObject(print, -1);
cout << "Reader thread " << m_serial << " begins to read file !" << endl;
ReleaseMutex(print);
Sleep(m_persist);
//退出线程
wait_to_print = WaitForSingleObject(print, -1);
cout << "Reader thread " << m_serial << " finished reading file !" << endl;
ReleaseMutex(print);
//阻塞互斥对象 Mutex2,保证对 readcount 的访问,修改互斥
wait_for_mutex1 = WaitForSingleObject(h_Mutex2, -1);
readcount--;
if (readcount == 0)
{
//最后一个读者,唤醒写者
LeaveCriticalSection(&cs_Write);
}
ReleaseMutex(h_Mutex2); //释放互斥信号
}
///
//写者优先---写者线程
//P:写者线程信息
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");
//从参数中获得信息
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); //延迟等待
cout << "Writer thread " << m_serial << " sents the writing require !" << endl;
wait_for_mutex3 = WaitForSingleObject(h_Mutex3, -1);
writecount++; //修改写者数目
if (writecount == 1)
{
EnterCriticalSection(&cs_Read);
}
ReleaseMutex(h_Mutex3);
EnterCriticalSection(&cs_Write);
cout << "Writer thread " << m_serial << " begins to write file !" << endl;
Sleep(m_persist);
cout << "Writer thread " << m_serial << " finished writing file !" << endl;
LeaveCriticalSection(&cs_Write);
wait_for_mutex3 = WaitForSingleObject(h_Mutex3, -1);
writecount--;
if (writecount == 0)
{
LeaveCriticalSection(&cs_Read);
}
ReleaseMutex(h_Mutex3);
}
/
//写者优先处理函数
// fileName:文件名
void WriterPriority(const char * fileName)
{
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 inFile;
inFile.open(fileName);
cout << "Writer Priority:" << endl;
while (inFile)
{
inFile >> thread_info[n_thread].serial;
inFile >> thread_info[n_thread].entity;
inFile >> thread_info[n_thread].delay;
inFile >> thread_info[n_thread++].persist;
inFile.get();
}
for (int i = 0; i < (int)(n_thread); i++)
{
if (thread_info[i].entity == 'R')
{
//创建读者进程
h_Thread[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(WP_ReaderThread), &thread_info[i], 0, &thread_ID);
}
else if (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);
cout << "All reader and writer have finished operating !" << endl;
}
/
//主函数
int main(void)
{
system("color 3f"); //改变颜色
const char * file = "test1.txt";
char ch;
while (1)
{
cout << "--------------------------------读者与写者问题---------------------------------" << endl;
cout << "*******************************************************************************" << endl;
cout << "* 1、读者优先 *" << endl;
cout << "* 2、写者优先 *" << endl;
cout << "* 3、退出... *" << endl;
cout << "*******************************************************************************" << endl;
printf("请选择(1,2,3): ");
do {
ch = (char)getchar();
} while (ch != '1'&&ch != '2'&&ch != '3');
system("cls"); //执行清屏幕命令
switch (ch)
{
case '1':
ReaderPriority(file);
break;
case '2':
WriterPriority(file);
break;
case '3':
return 0;
}
cout << endl << "按任意键继续..." << endl;
getchar();
system("cls");
}
return 0;
}
test1.txt内容:
1 R 3 5
2 W 4 5
3 R 5 2
4 R 6 5
5 W 5.1 3
结果: