zoukankan      html  css  js  c++  java
  • Windows操作系统实习之读者写者问题

    Visual Studio 2008

    参考(http://blog.csdn.net/melody_1208/article/details/2027507

    在Windows 下创建一个控制台进程,该进程应包含n个线程。用这n个线程来表示n个读者或写者。每个线程按相应测试数据文件(后面介绍)的要求进行读写操作。用信号量机制分别实现读者优先和写者优先的读者-写者问题。

    读者-写者问题的操作限制(包括读者优先和写者优先):

    1)写-写互斥,即不能有两个写者同时进行写操作。

    2)读-写互斥,即不能同时有一个线程在读,而另一个线程在写。

    3)读-读互斥,即可以有一个或多个读者在读。

    读者优先的附加限制:如果一个读者申请进行读操作时已有另一个读者正在进行读操作,则该读者可直接开始读操作。

    写者优先的附加限制:如果一个读者申请进行读操作时已有另一个写者在等待访问共享资源,则该读者必须等到没有写者出于等待状态后才能开始读操作。

    测试文件格式说明,下面是一个测试数据文件的例子:

    1 R 3 5
    2 W 4 5
    3 R 5 2
    4 R 6 5
    5 W 5.1 3
    6 R 15 4
    7 R 15 4

    View Code
    #include <Windows.h>
    #include <conio.h>
    #include <cstdlib>
    #include <stdio.h>
    #include <fstream>
    using namespace std;

    #define READER 'R'
    #define WRITER 'W'
    #define INTE_PER_SEC 1000 //interrupt number per second
    #define MAX_THREAD_NUM 64 //max thread number

    int readCount = 0;
    int writeCount = 0;

    CRITICAL_SECTION RP_Writer; //Critical Section
    CRITICAL_SECTION cs_Writer;
    CRITICAL_SECTION cs_Read;

    struct ThreadInfo
    {
    int serial; //the serial number of the thread
    char entity; //type of thread(reader or writer)
    double delay; //delay of thread
    double persist; //time of thread's read and write operation
    };

    void RP_ReaderThread(void *p);
    void RP_WriterThread(void *p);
    void ReaderPriority(char *file);

    void WP_ReaderThread(void *p);
    void WP_WriterThread(void *p);
    void WriterPriority(char *file);

    int main()
    {
    char ch;
    while (true)
    {
    printf("*************************************************\n");
    printf(" 1: Read Priority\n");
    printf(" 2: Writer Priority \n");
    printf(" 3: Exit\n");
    printf("*************************************************\n");
    printf("Enter your choice(1, 2 or 3)\n");

    //input is incorrect
    do
    {
    ch = (char)_getch();
    } while (ch != '1' && ch != '2' && ch != '3');

    //system("cls");
    if (ch == '3')
    return 0;
    else if(ch == '1')
    ReaderPriority("thread.dat");
    else
    WriterPriority("thread.dat");
    printf("\nPress Any Key to Continue:\n");
    _getch();
    //system("cls");
    }
    return 0;
    }

    void RP_ReaderThread(void *p)
    {
    //execlusive object
    HANDLE h_Mutex;
    h_Mutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "mutex_for_readCount");

    DWORD wait_for_mutex; //wait for the execlusive object
    DWORD m_delay; //delay time
    DWORD m_persist; //the time of read file operation
    int m_serial; //serical number of the thread

    //get the information from the parameter
    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); //wait for a little while

    printf("Reader thread %d sents the reading require \n", m_serial);

    wait_for_mutex = WaitForSingleObject(h_Mutex, -1);

    readCount++;
    if (readCount == 1)
    {
    //the first reader, wait for resource
    EnterCriticalSection(&RP_Writer);
    }
    ReleaseMutex(h_Mutex);

    printf("Reader thread %d begins to read file\n", m_serial);
    Sleep(m_persist);

    printf("Reader thread %d finished reading file\n", m_serial);
    wait_for_mutex = WaitForSingleObject(h_Mutex, -1);
    readCount--;
    if (readCount == 0)
    {
    //if all readers finished their operation, wake up the writer
    LeaveCriticalSection(&RP_Writer);
    printf("Reader thread %d leave the critical section\n", m_serial);
    }
    ReleaseMutex(h_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("Writer thread %d sents the writing require \n", m_serial);
    EnterCriticalSection(&RP_Writer);

    printf("Writer thread %d begins to write to the file\n", m_serial);
    Sleep(m_persist);

    printf("Writer thread %d finishing writing to the file \n", m_serial);

    LeaveCriticalSection(&RP_Writer);
    }

    void ReaderPriority(char *file)
    {
    DWORD n_thread = 0; //number of threads
    DWORD thread_ID; //thread ID
    DWORD wait_for_all; //wait for all threads

    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; //initialize readcount
    InitializeCriticalSection(&RP_Writer);
    fstream inFile;
    inFile.open(file);
    printf("Read Priority \n\n");
    while(inFile)
    {
    //Read every writer, reader's information
    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 == READER || thread_info[i].entity == 'r')
    {
    //create reader thread
    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 thread to terminate
    wait_for_all = WaitForMultipleObjects(n_thread, h_Thread, TRUE, -1);
    printf("All reader and writer have finished operating \n");
    }

    void WP_ReaderThread(void *p)
    {
    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; //latency time
    DWORD m_persist; //the time it used for reading the file
    int m_serial; //the serial number of the thread

    //get information from the parameter
    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("Reader thread %d sends the reading require \n", m_serial);
    wait_for_mutex1 = WaitForSingleObject(h_Mutex1, -1);

    //enter the reader's critical section
    EnterCriticalSection(&cs_Read);

    //block execlusive object mutex2, ensure the access, modify to readcount is execlusive
    wait_for_mutex2 = WaitForSingleObject(h_Mutex2, -1);
    readCount++;
    if (readCount == 1)
    {
    //if it is the first reader, wait for the writer finish
    EnterCriticalSection(&cs_Writer);
    }
    ReleaseMutex(h_Mutex2);

    //let other reader enter the critical section
    LeaveCriticalSection(&cs_Read);
    ReleaseMutex(h_Mutex1);

    //read file
    printf("Reader thread %d begins to read file \n", m_serial);
    //block exevlusive object mutex2, ensure the access, modify to readcount is execlusive
    wait_for_mutex2 = WaitForSingleObject(h_Mutex2, -1);
    readCount--;
    if (readCount == 0)
    {
    //the last reader, wake up writer
    LeaveCriticalSection(&cs_Writer);
    }
    ReleaseMutex(h_Mutex2);
    }

    void WP_WriterThread(void *p)
    {
    DWORD m_delay;
    DWORD m_persist;
    int m_serial;
    DWORD wait_for_mutex3;
    HANDLE h_Mutex3;
    h_Mutex3 = OpenMutex(MUTEX_ALL_ACCESS, FALSE,"mutex3");

    //get information from the parameter
    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("Writer thread %d sends the writing require\n", m_serial);

    wait_for_mutex3 = WaitForSingleObject(h_Mutex3, -1);
    writeCount++;
    if (writeCount == 1)
    {
    //the first writer, wait for the read finsih
    EnterCriticalSection(&cs_Read);
    }
    ReleaseMutex(h_Mutex3);

    //enter the writer critical section
    EnterCriticalSection(&cs_Writer);

    //write the file
    printf("Write thread %d begins to write to the file \n", m_serial);
    Sleep(m_persist);

    //exit the thread
    printf("Write thread %d finishing writing to the file\n", m_serial);
    //leave the critical section
    LeaveCriticalSection(&cs_Writer);

    wait_for_mutex3 = WaitForSingleObject(h_Mutex3, -1);
    writeCount--;
    if (writeCount == 0)
    {
    //writer finished, reader can read
    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");

    //thread object
    HANDLE h_Thread[MAX_THREAD_NUM];
    ThreadInfo thread_info[MAX_THREAD_NUM];

    readCount = 0;
    writeCount = 0;
    InitializeCriticalSection(&cs_Writer);
    InitializeCriticalSection(&cs_Read);
    fstream inFile;
    inFile.open(file);
    printf("Write Priority \n\n");
    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 == READER || thread_info[i].entity == 'r')
    {
    //create reader thread
    h_Thread[i] = CreateThread(NULL, 0,
    (LPTHREAD_START_ROUTINE)(WP_ReaderThread),
    &thread_info[i],
    0,
    &thread_ID);
    }
    else
    {
    //create writer thread
    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");
    }



  • 相关阅读:
    洛谷—— P2234 [HNOI2002]营业额统计
    BZOJ——3555: [Ctsc2014]企鹅QQ
    CodeVs——T 4919 线段树练习4
    python(35)- 异常处理
    August 29th 2016 Week 36th Monday
    August 28th 2016 Week 36th Sunday
    August 27th 2016 Week 35th Saturday
    August 26th 2016 Week 35th Friday
    August 25th 2016 Week 35th Thursday
    August 24th 2016 Week 35th Wednesday
  • 原文地址:https://www.cnblogs.com/leealvin/p/2430879.html
Copyright © 2011-2022 走看看