在 reader-writer 问题中什么时候唤醒 writer?在释放互斥锁之前还是之后?
When to wake up writer in reader-writer problem? before releasing mutex or after?
我想知道在我的情况下最佳做法是什么。
在下面的代码中,我在解锁互斥锁之前向作者发出信号
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;
}
我的实现基于找到的伪代码(此处)[
正确性无关紧要-两者都可以,并且没有死锁。
在使用不同线程优先级的情况下,在解锁互斥量之前通知条件变量的实现可以确保等待条件变量的 higher-priority 线程将获得互斥量优先于 lower-priority 正在等待互斥体的线程。
我想知道在我的情况下最佳做法是什么。 在下面的代码中,我在解锁互斥锁之前向作者发出信号
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;
}
我的实现基于找到的伪代码(此处)[
正确性无关紧要-两者都可以,并且没有死锁。
在使用不同线程优先级的情况下,在解锁互斥量之前通知条件变量的实现可以确保等待条件变量的 higher-priority 线程将获得互斥量优先于 lower-priority 正在等待互斥体的线程。