0

我想知道在我的情况下最好的做法是什么。在下面的代码中,我在解锁互斥锁之前向作者发出信号

void* Reader(void *context)
{
    while(TRUE)
    {
        LOCK(&g_mutex);
        ++g_activeReaders;
        UNLOCK(&g_mutex);

        printf("reader: %ld counter val: %d ", (long)context, g_counter);

        LOCK(&g_mutex);
        --g_activeReaders;
        printf("g_activeReaders: %d \n", g_activeReaders);
        if(0 == g_activeReaders)
        {
            SIGNAL(&g_cv);
        }
        UNLOCK(&g_mutex);
    }

    return NULL;
}

我想知道这是否出于某种原因更好,以防止死锁

void* Reader(void *context)
{
    int signalFlag;
        while(TRUE)
    {
                signalFlag = 0;
        LOCK(&g_mutex);
        ++g_activeReaders;
        UNLOCK(&g_mutex);

        printf("reader: %ld counter val: %d ", (long)context, g_counter);

        LOCK(&g_mutex);
        --g_activeReaders;
        printf("g_activeReaders: %d \n", g_activeReaders);
        if(0 == g_activeReaders)
        {
                        signalFlag = 1;
        }
        UNLOCK(&g_mutex);

                if(signalFlag)
                SIGNAL(&g_cv);
    }


    return NULL;
}

我的完整程序是:

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

pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t g_cv = PTHREAD_COND_INITIALIZER;
int g_activeReaders = 0;
int g_counter;

#define LOCK(X) pthread_mutex_lock(X)
#define UNLOCK(X) pthread_mutex_unlock(X)
#define WAIT pthread_cond_wait
#define WAKE_ALL pthread_cond_broadcast
#define SIGNAL pthread_cond_signal
#define JOIN pthread_join
#define TRUE 1
#define N 3

void* Writer(void * context)
{
    while(TRUE)
    {
        LOCK(&g_mutex);
        while(g_activeReaders)
        {
            WAIT(&g_cv, &g_mutex);
        }

        ++g_counter;
        UNLOCK(&g_mutex);
    }

    return NULL;
}

void* Reader(void *context)
{
    while(TRUE)
    {
        LOCK(&g_mutex);
        ++g_activeReaders;
        UNLOCK(&g_mutex);

        printf("reader: %ld counter val: %d ", (long)context, g_counter);

        LOCK(&g_mutex);
        --g_activeReaders;
        printf("g_activeReaders: %d \n", g_activeReaders);
        if(0 == g_activeReaders)
        {
            SIGNAL(&g_cv);
        }
        UNLOCK(&g_mutex);
    }

    return NULL;
}

void InitWriters(pthread_t* writers, int count)
{
    int status;
    int i;

    for(i = 0; i < count; ++i)
    {
        status = pthread_create(&writers[i], NULL, Writer, NULL);

        if(status)
        {
            fprintf(stderr, "Writer create fail\n");
            exit(-1);
        }
    }
}

void InitReaders(pthread_t* readers, int count)
{
    int status;
    int i;

    for(i = 0; i < count; ++i)
    {
        long e = i;
        status = pthread_create(&readers[i], NULL, Reader, (void*) e);

        if(status)
        {
            fprintf(stderr, "readers create fail\n");
            exit(-1);
        }
    }
}

void JoinThreads(pthread_t* threads, int count)
{
    int status;
    int i;

    for(i = 0; i < count; ++i)
    {
        status = pthread_join(threads[i], NULL);

        if(status)
        {
            fprintf(stderr, "readers create fail\n");
            exit(-1);
        }
    }
}

int main(void)
{
    pthread_t writer;
    pthread_t readers[N];

    InitWriters(&writer, 1);
    InitReaders(readers, N);

    JoinThreads(&writer, 1);
    JoinThreads(readers, N);

    pthread_cond_destroy(&g_cv);
    pthread_mutex_destroy(&g_mutex);

    return 0;
}

我的实现基于找到的伪代码(此处)[ C 中的读取器/写入器实现

4

1 回答 1

0

正确性无关紧要-两者都可以,并且没有死锁。

在您使用不同线程优先级的情况下,在解锁互斥锁之前发出条件变量信号的实现可以确保等待条件变量的高优先级线程将优先于低优先级线程获得互斥锁那只是在互斥体上等待。

于 2019-07-14T14:14:55.543 回答