簡體   English   中英

讀寫器優先級問題的讀寫器問題

[英]Reader Writer Problem With Writer Priority Problem

當我更多地了解操作系統時,我遇到了這個問題。 在我的代碼中,我嘗試讓閱讀器具有優先權並且它起作用了,所以接下來我對其進行了一些修改以使作者具有優先權。 當我運行代碼時,output 完全一樣,似乎作者沒有優先權。 這是帶有注釋的代碼。 我不確定我做錯了什么,因為我修改了很多代碼,但是如果我根本不更改 output 仍然保持不變。

#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>

/*
This program provides a possible solution for first readers writers problem using mutex and semaphore.
I have used 10 readers and 5 producers to demonstrate the solution. You can always play with these values.
*/

// Semaphore initialization for writer and reader 
sem_t wrt;
sem_t rd;

// Mutex 1 blocks other readers, mutex 2 blocks other writers
pthread_mutex_t mutex1;
pthread_mutex_t mutex2;

// Value the writer is changing, we are simply multiplying this value by 2
int cnt = 2;

int numreader = 0;
int numwriter = 0;

void *writer(void *wno)
{   
    pthread_mutex_lock(&mutex2);
    numwriter++;
    if(numwriter == 1){
        sem_wait(&rd);      
    }
    pthread_mutex_unlock(&mutex2);
    sem_wait(&wrt); 

    // Writing Section
    cnt = cnt*2;
    printf("Writer %d modified cnt to %d\n",(*((int *)wno)),cnt);

    sem_post(&wrt);
    pthread_mutex_lock(&mutex2);
    numwriter--;
    if(numwriter == 0){
        sem_post(&rd);
    }
    pthread_mutex_unlock(&mutex2); 

}
void *reader(void *rno)
{   
    sem_wait(&rd);
    pthread_mutex_lock(&mutex1);
    numreader++;
    if(numreader == 1){
        sem_wait(&wrt);
    }
    pthread_mutex_unlock(&mutex1);
    sem_post(&rd); 

    // Reading Section
    printf("Reader %d: read cnt as %d\n",*((int *)rno),cnt);

    
    pthread_mutex_lock(&mutex1);
    numreader--;
    if(numreader == 0){
        sem_post(&wrt);
    }
    pthread_mutex_unlock(&mutex1); 
}

int main()
{   

    pthread_t read[10],write[5];
    pthread_mutex_init(&mutex1, NULL);
    pthread_mutex_init(&mutex2, NULL);
    sem_init(&wrt,0,1);
    sem_init(&rd,0,1);

    int a[10] = {1,2,3,4,5,6,7,8,9,10}; //Just used for numbering the writer and reader

    for(int i = 0; i < 5; i++) {
        pthread_create(&write[i], NULL, (void *)writer, (void *)&a[i]);
    }

    for(int i = 0; i < 10; i++) {
        pthread_create(&read[i], NULL, (void *)reader, (void *)&a[i]);
    }

    for(int i = 0; i < 5; i++) {
        pthread_join(write[i], NULL);
    }

    for(int i = 0; i < 10; i++) {
        pthread_join(read[i], NULL);
    }

    pthread_mutex_destroy(&mutex1);
    pthread_mutex_destroy(&mutex2);
    sem_destroy(&wrt);
    sem_destroy(&rd);

    return 0;
    
}

Output (兩者都是一樣的。我認為如果作家有優先權,它會先改變,然后再被閱讀): 在此處輸入圖像描述

替代語義

您想做的大部分事情都可以用更少的開銷來完成。 例如,在經典的讀寫器問題中,讀者不需要阻止其他讀者。

您也許可以將讀寫器模式替換為發布者-消費者模式,該模式通過獲取-消費 memory 排序管理指向數據塊的指針。 如果一個線程在最初編寫后需要更新 memory 的同一塊,則根本只需要鎖定。

POSIX 和 Linux 在系統庫中實現了讀寫鎖,旨在避免飢餓。 這很可能是您想要的高級構造。

如果您仍想實現自己的,一種實現將使用當前讀者的計數、待處理的寫入者的計數和指示寫入是否正在進行的標志。 它將所有這些值打包到一個原子位域中,並通過比較和交換來更新該位域。

讀取器線程將檢索該值,檢查是否有飢餓的寫入器在等待,如果沒有,則增加讀取器的計數。 如果有寫入器,它會后退(可能會旋轉並讓出 CPU,可能會在條件變量上休眠)。 如果正在進行寫入,它會等待完成。 如果它只看到正在進行的其他讀取,它會繼續。

寫入器線程將檢查是否有任何讀取或寫入正在進行。 如果是這樣,它們會增加等待寫入者的數量,然后等待。 如果不是,他們設置寫入進行位並繼續。

將所有這些字段打包到同一個原子位域中可以保證沒有線程認為使用緩沖區是安全的,而另一個線程認為寫入是安全的:如果兩個線程嘗試同時更新 state,一個總是會失敗。

如果你堅持使用信號量

您仍然可以讓讀取器線程檢查寫入器信號量上的sem_getvalue() ,如果他們看到任何飢餓的寫入器正在等待,則退出。 一種方法是等待條件變量,線程在完成緩沖區時發出信號。 讀取器在寫入器等待時看到它持有互斥鎖,可以嘗試喚醒一個寫入器線程,然后 go 重新進入睡眠狀態,而只看到其他讀取器在等待的讀取器可以喚醒一個讀取器,這將喚醒下一個讀取器, 等等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM