如何在 reader-writer 问题中检测饥饿

How to detect starvation in reader-writer problem

我对这段代码有疑问。这是经典的 readers-writers 问题。我按照这个维基百科页面上找到的伪代码来解决第一个让作家挨饿的问题。我想知道我是如何真正注意到作家们正在挨饿的。

我尝试将 shared_variable 的打印语句放在不同的地方,但这并没有给我太多启发。但也许我只是不明白发生了什么。有人能向我解释我是如何从视觉上看到饥饿发生的吗?谢谢! reader 或 writer 尝试读取或写入的尝试次数作为命令行参数给出。

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


// Compile it like so: gcc assignment2.c -lpthread


// Shared variables (semaphore and integer)
static sem_t rw_mutex;
static sem_t mutex;
static int read_count = 0;

// Shared variable
int shared_variable = 0;

static void *writerAction(void *arg){
    int number_attempt = *((int *) arg);
    int attempt = 0;
    do{
        sem_wait(&rw_mutex);
        shared_variable = shared_variable + 10;
        sem_post(&rw_mutex);
        attempt++;
    }while(attempt < number_attempt);
}

static void *readerAction(void *arg){
    int number_attempt = *((int *) arg);
    int attempt = 0;
   do{
        sem_wait(&mutex);
        read_count++;
        // waiting to be able to read for the possible writer
        if (read_count == 1 ){
            sem_wait(&rw_mutex); // get the lock so that writter can't write!
        }

        // Release the read_count variable
        sem_post(&mutex);
        sem_wait(&mutex);
        read_count--;

        if (read_count == 0){
            sem_post(&rw_mutex); // release the lock so that writter can write
        }
        sem_post(&mutex);
        attempt++;
    } while(attempt < number_attempt);
}




int main(int argc, char *argv[]) {

    int number_writers = 10;
    int number_readers = 500;
    int reader_repeat_count = atoi(argv[2]);
    int writer_repeat_count = atoi(argv[1]);

    // Instantiating the threads for the writters and readers
    pthread_t writer_threads[number_writers];
    pthread_t reader_threads[number_readers];

    // Initation of semaphores
    sem_init(&rw_mutex, 0, 1);
    sem_init(&mutex, 0, 1);

    printf("Start creation of Readers\n");
    for(int i = 0; i <number_readers; i++){
        pthread_create(&reader_threads[i], NULL, readerAction, &reader_repeat_count);
    }
    printf("Start creation of Writers\n");
    for(int i = 0; i < number_writers; i++){
        pthread_create(&writer_threads[i], NULL, writerAction, &writer_repeat_count);
    }

    // All the actions is hapenning here
    printf("Wait for Readers\n");
    for(int i = 0; i < number_readers; i++){
        printf("Waiting for : %d\n",i);
        pthread_join(reader_threads[i], NULL);
    }

    printf("Wait for Writers\n");
    // Collect all the writers
    for(int i = 0; i < number_writers; i++){
        printf("Waiting for : %d\n",i);
        pthread_join(writer_threads[i], NULL);
    }

    // Results
    printf("The shared variable is : %d\n",shared_variable);
   }

首先是语法错误,return类型的writerAction和readerAction应该是void而不是void*

为了查看 writer 饥饿,您可以在 writer 试图获取 rw_mutex 之前打印 "writer trying to write",调用 sem_wait(&rw_mutex)。当作者更新了关键部分内的共享变量时,添加另一个打印。在 reader 的入口部分之后再添加一个 printf。这是什么代码。

// Release the read_count variable
sem_post(&mutex);
printf("reader reading shared value %d\n", shared_variable);

现在,当您 运行 具有大量重复计数的代码时,您将看到 "writer trying to write" 然后您将看到大量 reader 打印输出,而不是作者更新共享变量,这将证明 reader 不允许作者更新变量,从而使作者挨饿。