[C/C++ löst das Reader-Writer-Problem]

1. Problembeschreibung

Es gibt zwei Sätze gleichzeitiger Prozesse, Lese- und Schreibvorgänge, die eine Datei gemeinsam nutzen. Wenn zwei oder mehr Leseprozesse (nur Daten lesen), hat dies keinen Einfluss auf die Daten, und Verbraucher nehmen die Daten weg, wenn sie die Daten lesen, sodass zwei Verbraucher dies nicht können Daten gemeinsam lesen) Beim gleichzeitigen Zugriff auf gemeinsam genutzte Daten treten keine Nebenwirkungen auf. Wenn jedoch ein Schreibvorgang und andere Prozesse (Lesevorgang oder Schreibvorgang) gleichzeitig auf gemeinsam genutzte Daten zugreifen, kann es zu Dateninkonsistenzfehlern kommen.
Daher ist Folgendes erforderlich:

  1. Erlauben Sie mehreren Lesern, gleichzeitig Lesevorgänge für die Datei durchzuführen.
  2. Nur ein Autor darf Informationen in die Datei schreiben.
  3. Kein Autor erlaubt anderen Lesern oder Autoren nicht, zu arbeiten, bis der Schreibvorgang abgeschlossen ist;
  4. Bevor der Writer den Schreibvorgang ausführt, sollten alle vorhandenen Reader und Writer beendet werden.

2. Problemanalyse

  • Analysieren Sie zunächst die synchrone gegenseitige Ausschlussbeziehung im Problem. Leser und Autoren schließen sich gegenseitig aus, Schriftsteller und Autoren schließen sich gegenseitig aus und Leser und Leser schließen sich nicht gegenseitig aus.
  • Betrachten Sie zweitens den Fall, dass Lese- und Schreibprozesse gleichzeitig ausgeführt werden. Wenn Leser und Schreiber gleichzeitig Daten lesen oder schreiben, sollten wir dem Leseprozess, dem Schreibprozess oder der Lese-Schreib-Fairness Priorität einräumen.
  • Schließlich soll das Semaphor die gegenseitige Ausschlussbeziehung und die Prioritätsausführungsstrategie zwischen Lesern und Autoren steuern.

Drei, drei Strategien, die es zu erreichen gilt

/*  本项目仅用于模拟解决读者-写者问题。
    1.包含若干读者线程和写者线程用于模拟读者进程和写者进程。
    2.包含一个单个资源临界缓冲区用于存放和读取数据。
    3.分别实现读者优先、写者优先以及读写公平三种策略。
*/

1. Strategie „Leser zuerst“.

Fügen Sie hier eine Bildbeschreibung ein
ReadHighPriority.cpp

#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>

#define NUM_READERS 3   //读者进程数量
#define NUM_WRITERS 2   //写者进程数量

static int data = 0;   //初始化临界缓存区为空
static int readers_count = 0;  //记录读者进程数量
static HANDLE mutex;   //用于实现读者进程对于readers_count变量的互斥访问
static HANDLE rw_semaphore;    //用于实现读者和写者互斥访问临界缓冲区

static DWORD WINAPI Reader(LPVOID lpParam) {
    
    
    int reader_id = *(int*)lpParam;

    while (1) {
    
    
        WaitForSingleObject(mutex, INFINITE);
        readers_count++;
        if (readers_count == 1) {
    
    
            WaitForSingleObject(rw_semaphore, INFINITE);
        }
        ReleaseMutex(mutex);

        printf("Reader %d is reading data: %d\n", reader_id, data);
        Sleep(1000);  // 模拟读取数据的耗时

        WaitForSingleObject(mutex, INFINITE);
        readers_count--;
        if (readers_count == 0) {
    
    
            ReleaseSemaphore(rw_semaphore, 1, NULL);
        }
        ReleaseMutex(mutex);

        Sleep(2000);  // 读者休息一段时间后再次读取数据
    }

    return 0;
}

DWORD WINAPI Writer(LPVOID lpParam) {
    
    
    int writer_id = *(int*)lpParam;

    while (1) {
    
    
        WaitForSingleObject(rw_semaphore, INFINITE);

        data++;  // 写入数据
        printf("Writer %d is writing data: %d\n", writer_id, data);
        Sleep(2000);  // 模拟写入数据的耗时

        ReleaseSemaphore(rw_semaphore, 1, NULL);

        Sleep(3000);  // 写者休息一段时间后再次写入数据
    }

    return 0;
}

int main() {
    
    
    // 创建互斥锁和读写信号量
    mutex = CreateMutex(NULL, FALSE, NULL);
    rw_semaphore = CreateSemaphore(NULL, 1, 1, NULL);

    // 创建读者线程
    HANDLE reader_threads[NUM_READERS];
    int reader_ids[NUM_READERS];
    for (int i = 0; i < NUM_READERS; i++) {
    
    
        reader_ids[i] = i + 1;
        reader_threads[i] = CreateThread(NULL, 0, Reader, &reader_ids[i], 0, NULL);
    }

    // 创建写者线程
    HANDLE writer_threads[NUM_WRITERS];
    int writer_ids[NUM_WRITERS];
    for (int i = 0; i < NUM_WRITERS; i++) {
    
    
        writer_ids[i] = i + 1;
        writer_threads[i] = CreateThread(NULL, 0, Writer, &writer_ids[i], 0, NULL);
    }

    // 等待所有读者线程和写者线程结束
    WaitForMultipleObjects(NUM_READERS, reader_threads, TRUE, INFINITE);
    WaitForMultipleObjects(NUM_WRITERS, writer_threads, TRUE, INFINITE);

    // 关闭句柄
    CloseHandle(mutex);
    CloseHandle(rw_semaphore);

    return 0;
}

2. Lesen und schreiben Sie die Fairness-Strategie

Fügen Sie hier eine Bildbeschreibung ein

ReadrWriterEqualPriority.cpp

#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>

#define NUM_READERS 3   //读者进程数量
#define NUM_WRITERS 2   //写者进程数量

static int data = 0;   //初始化临界缓存区为空
static int readers_count = 0;  //记录读者进程数量
static HANDLE mutex;   //用于实现读者进程对于readers_count变量的互斥访问
static HANDLE rw_semaphore;    //用于实现读者和写者互斥访问临界缓冲区
static HANDLE w_priority;   //用于实现写优先

static DWORD WINAPI Reader(LPVOID lpParam) {
    
    
    int reader_id = *(int*)lpParam;

    while (1) {
    
    
        WaitForSingleObject(w_priority, INFINITE);
        WaitForSingleObject(mutex, INFINITE);
        readers_count++;
        if (readers_count == 1) {
    
    
            WaitForSingleObject(rw_semaphore, INFINITE);
        }
        ReleaseMutex(mutex);
        ReleaseSemaphore(w_priority, 1, NULL);

        printf("Reader %d is reading data: %d\n", reader_id, data);
        Sleep(1000);  // 模拟读取数据的耗时

        WaitForSingleObject(mutex, INFINITE);
        readers_count--;
        if (readers_count == 0) {
    
    
            ReleaseSemaphore(rw_semaphore, 1, NULL);
        }
        ReleaseMutex(mutex);

        Sleep(2000);  // 读者休息一段时间后再次读取数据
    }

    return 0;
}

DWORD WINAPI Writer(LPVOID lpParam) {
    
    
    int writer_id = *(int*)lpParam;

    while (1) {
    
    
        WaitForSingleObject(w_priority, INFINITE);
        WaitForSingleObject(rw_semaphore, INFINITE);

        data++;  // 写入数据
        printf("Writer %d is writing data: %d\n", writer_id, data);
        Sleep(2000);  // 模拟写入数据的耗时

        ReleaseSemaphore(rw_semaphore, 1, NULL);
        ReleaseSemaphore(w_priority, 1, NULL);

        Sleep(3000);  // 写者休息一段时间后再次写入数据
    }

    return 0;
}

int main() {
    
    
    // 创建互斥锁和读写信号量
    mutex = CreateMutex(NULL, FALSE, NULL);
    rw_semaphore = CreateSemaphore(NULL, 1, 1, NULL);
    w_priority = CreateSemaphore(NULL,1,1,NULL);

    // 创建读者线程
    HANDLE reader_threads[NUM_READERS];
    int reader_ids[NUM_READERS];
    for (int i = 0; i < NUM_READERS; i++) {
    
    
        reader_ids[i] = i + 1;
        reader_threads[i] = CreateThread(NULL, 0, Reader, &reader_ids[i], 0, NULL);
    }

    // 创建写者线程
    HANDLE writer_threads[NUM_WRITERS];
    int writer_ids[NUM_WRITERS];
    for (int i = 0; i < NUM_WRITERS; i++) {
    
    
        writer_ids[i] = i + 1;
        writer_threads[i] = CreateThread(NULL, 0, Writer, &writer_ids[i], 0, NULL);
    }

    // 等待所有读者线程和写者线程结束
    WaitForMultipleObjects(NUM_READERS, reader_threads, TRUE, INFINITE);
    WaitForMultipleObjects(NUM_WRITERS, writer_threads, TRUE, INFINITE);

    // 关闭句柄
    CloseHandle(mutex);
    CloseHandle(rw_semaphore);
    CloseHandle(w_priority);
    return 0;
}

3. Autorenprioritätsstrategie (spätere Aktualisierungen)

Supongo que te gusta

Origin blog.csdn.net/wddkxg/article/details/131427742
Recomendado
Clasificación