读者写者问题 代码

#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

猜你喜欢

转载自blog.csdn.net/Puppet__/article/details/85061933