【多线程】互斥与同步(读者与写者问题,读者优先)

描述:有一个写者很多读者,多个读者可以同时读文件,但写者在写文件时不允许有读者在读文件,同样有读者在读文件时写者也不去能写文件。


解决方案之一:使用信号量。

处于等待的情况有以下几种:

第一.写者要等到没有读者时才能去写文件。

第二.所有读者要等待写者完成写文件后才能去读文件。

描述代码:

int readcount;
semphore Mutex,rcMutex;
void reader() {
    while(true) {
        semWait(rcMutex);
        readcount++;
        if(readcount == 1) {
            semWait(Mutex);
        }
        semSignal(rcMutex);
        READ();
        semWait(rcMutex);
        readcount--;
        if(readcount == 0) {
            semSignal(Mutex);
        }
        semSignal(rcMutex);
    }
}
void writer() {
    while(true) {
        semWait(Mutex);
        WRITE();
        semSignal(Mutex);
    }
}

void main() {
    readcount = 0;
    parBegin(reader,writer);
}
实现代码:
/// 读者写者问题(读者优先)
#include <windows.h>
#include <iostream>

unsigned short readID; ///读操作的进程号
unsigned short writeID; ///写操作的进程号
HANDLE rcMutex = NULL;///用于对readCount的互斥访问
HANDLE Mutex = NULL;///用于对临界区的互斥访问
int readCount = 0;///读者数量
bool p_ccontinue = true; ///控制程序结束


///读操作
void read() {
    readID = GetCurrentThreadId();
    std::cout << "Reading " << readID << " ... ";
    std::cout << "Succeed" << std::endl;
}
///写操作
void write() {
    writeID = GetCurrentThreadId();
    std::cout << "Writing " << writeID << " ... ";
    std::cout << "Succeed" << std::endl;
}
///读者
DWORD WINAPI Reader(LPVOID lpPara) {
    while (true) {
        WaitForSingleObject(rcMutex, INFINITE);///P(rcMutex)
        readCount++;
        if (readCount == 1) {
            ///如果是第一个读者,那么限制写者的访问
            std::cout<<"\n\t第一个读者\n";
            WaitForSingleObject(Mutex, INFINITE);/// P(Mutex)
        }
        ReleaseMutex(rcMutex);/// V(rcMutex)
        read();
        Sleep(1500);
        WaitForSingleObject(rcMutex, INFINITE);/// P(rcMutex)
        readCount--;
        if (readCount == 0) {
            ///如果是最后一个读者,那么释放以供写者或读者访问
            std::cout<<"\t最后一个读者\n";
            ReleaseMutex(Mutex);/// V(Mutex)
        }
        ReleaseMutex(rcMutex);/// V(rcMutex)
    }
}
///写者
DWORD WINAPI Writer(LPVOID lpPara) {
    while (true) {
        WaitForSingleObject(Mutex, INFINITE);/// P(Mutex)
        write();
        Sleep(1500);
        ReleaseMutex(Mutex);/// V(Mutex)
    }
}

int main() {
    /// 创建互斥信号量
    rcMutex = CreateMutex(NULL, false, NULL);
    Mutex = CreateMutex(NULL, false, NULL);
    
    const unsigned short READERS_COUNT = 2; ///读者的个数
    const unsigned short WRITERS_COUNT = 2; ///写者的个数
    const unsigned short THREADS_COUNT = READERS_COUNT+WRITERS_COUNT;    ///总的线程数
    HANDLE hThreads[THREADS_COUNT]; ///各线程的 handle
    DWORD readerID[READERS_COUNT];
    DWORD writerID[WRITERS_COUNT];
    ///创建读者线程
    for (int i = 0; i < READERS_COUNT; i++) {
        hThreads[i] = CreateThread(NULL, 0, Reader, NULL, 0, &readerID[i]);
        if (hThreads[i]==NULL)
            return -1;
    }
    ///创建写者线程
    for (int i = 0; i < WRITERS_COUNT; i++) {
        hThreads[READERS_COUNT+i] = CreateThread(NULL, 0, Writer, NULL, 0, &writerID[i]);
        if (hThreads[i]==NULL)
            return -1;
    }
    while(p_ccontinue) {
        if(getchar()) { ///按回车后终止程序运行
            p_ccontinue = false;
        }
    }
    return 0;
}

部分参考:https://blog.csdn.net/morewindows/article/details/7596034


猜你喜欢

转载自blog.csdn.net/feng_zhiyu/article/details/80884370