reader-作者访问多个 readers
reader-writer accessing multiple readers
在 UNIX 中实现 WRITER-READER 问题时,我有几个问题无法解决。
第一个是我不知道,如何修改代码才能像线程总是调用进入阅览室一样工作。例如,当一位作家在阅览室时,reader 正在等待进入阅览室。当作家逃离阅览室和readers进入阅览室时,他还在等待机会。
第二个是不知道怎么修改代码才能让几个reader进入阅览室。在我的代码中,阅览室中只能同时有一个线程。
第三个是,如何识别 writer 或 reader 是否正在挨饿?我的代码中哪一个正在挨饿?
代码如下:
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#define READERS 15
#define WRITERS 10
int bufferw = 0, bufferr = 0, counterw = WRITERS, counterr = READERS;
int i;
pthread_mutex_t mwrite, mread;
pthread_cond_t condw, condr;
pthread_t r[READERS], w[WRITERS];
void *writer(void *ptr) {
pthread_mutex_lock(&mwrite);
{
counterr = READERS;
counterw = WRITERS;
++bufferw;
for(i=0; i<READERS; i++) while(bufferr > 0) pthread_cond_wait(&condw, &r[i]);
printf("WRITER ENTERING!");
pthread_mutex_unlock(&mwrite);
bufferw--;
}
pthread_cond_signal(&condr);
pthread_exit(0);
}
void *reader(void *ptr) {
counterr = READERS;
counterw = WRITERS;
{
++bufferr;
for(i=0; i<WRITERS; i++) while(bufferw == 1) pthread_cond_wait(&condr, &w[i]);
printf("READER ENTERING!");
bufferr = 0;
}
pthread_cond_signal(&condw);
pthread_exit(0);
}
int main(int argc, char* argv[]) {
pthread_mutex_init(&mwrite, 0);
pthread_mutex_init(&mread, 0);
pthread_cond_init(&condw, 0);
pthread_cond_init(&condr, 0);
for(i=0; i<WRITERS; i++) pthread_create(&w[i], NULL, writer, NULL);
for(i=0; i<READERS; i++) pthread_create(&r[i], NULL, reader, NULL);
for(i=0; i<WRITERS; i++) pthread_join(w[i], NULL);
for(i=0; i<READERS; i++) pthread_join(r[i], NULL);
pthread_cond_destroy(&condw);
pthread_cond_destroy(&condr);
pthread_mutex_destroy(&mwrite);
pthread_mutex_destroy(&mread);
return 0;
}
在此先感谢您的帮助!
EDIT:// 在这种情况下我怎样才能避免比赛?
您可以使用一个互斥量和两个条件变量来实现这一点。
reader( ) {
pthread_mutex_lock(&m);
while (!(writers == 0))
pthread_cond_wait(&readersQ, &m);
readers++;
pthread_mutex_unlock(&m);
/* actual read */
pthread_mutex_lock(&m);
if (--readers == 0)
pthread_cond_signal(&writersQ);
pthread_mutex_unlock(&m);
}
writer( ) {
pthread_mutex_lock(&m);
writers++;
while (!((readers == 0) && (active_writers == 0))) {
pthread_cond_wait(&writersQ, &m);
}
active_writers++;
pthread_mutex_unlock(&m);
/* actual write */
pthread_mutex_lock(&m);
writers--;
active_writers--;
if (writers > 0)
pthread_cond_signal(&writersQ);
else
pthread_cond_broadcast(&readersQ);
pthread_mutex_unlock(&m);
}
此实施对 readers 不公平,这意味着如果有作者在写作,readers 将永远没有阅读的选择。这是因为写作比阅读更重要。如果你不这么认为,我也可以提供一个对作者不公平的版本。
reader 将选择只读当 writers 为零时。如果只有一个writer,writer不会为0,reader无法读取。
如果有多个写入者,变量active_writers将确保一次只能写入一个写入者。
编辑
以下是饿死作者的版本。对于 reader,它是相同的代码。
writer( ) {
pthread_mutex_lock(&m);
while(!((readers == 0) &&(writers == 0)))
pthread_cond_wait(&writersQ, &m);
writers++;
pthread_mutex_unlock(&m);
/* actual write */
pthread_mutex_lock(&m);
writers--;
pthread_cond_signal(&writersQ);
pthread_cond_broadcast(&readersQ);
pthread_mutex_unlock(&m);
}
在 UNIX 中实现 WRITER-READER 问题时,我有几个问题无法解决。 第一个是我不知道,如何修改代码才能像线程总是调用进入阅览室一样工作。例如,当一位作家在阅览室时,reader 正在等待进入阅览室。当作家逃离阅览室和readers进入阅览室时,他还在等待机会。 第二个是不知道怎么修改代码才能让几个reader进入阅览室。在我的代码中,阅览室中只能同时有一个线程。 第三个是,如何识别 writer 或 reader 是否正在挨饿?我的代码中哪一个正在挨饿?
代码如下:
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#define READERS 15
#define WRITERS 10
int bufferw = 0, bufferr = 0, counterw = WRITERS, counterr = READERS;
int i;
pthread_mutex_t mwrite, mread;
pthread_cond_t condw, condr;
pthread_t r[READERS], w[WRITERS];
void *writer(void *ptr) {
pthread_mutex_lock(&mwrite);
{
counterr = READERS;
counterw = WRITERS;
++bufferw;
for(i=0; i<READERS; i++) while(bufferr > 0) pthread_cond_wait(&condw, &r[i]);
printf("WRITER ENTERING!");
pthread_mutex_unlock(&mwrite);
bufferw--;
}
pthread_cond_signal(&condr);
pthread_exit(0);
}
void *reader(void *ptr) {
counterr = READERS;
counterw = WRITERS;
{
++bufferr;
for(i=0; i<WRITERS; i++) while(bufferw == 1) pthread_cond_wait(&condr, &w[i]);
printf("READER ENTERING!");
bufferr = 0;
}
pthread_cond_signal(&condw);
pthread_exit(0);
}
int main(int argc, char* argv[]) {
pthread_mutex_init(&mwrite, 0);
pthread_mutex_init(&mread, 0);
pthread_cond_init(&condw, 0);
pthread_cond_init(&condr, 0);
for(i=0; i<WRITERS; i++) pthread_create(&w[i], NULL, writer, NULL);
for(i=0; i<READERS; i++) pthread_create(&r[i], NULL, reader, NULL);
for(i=0; i<WRITERS; i++) pthread_join(w[i], NULL);
for(i=0; i<READERS; i++) pthread_join(r[i], NULL);
pthread_cond_destroy(&condw);
pthread_cond_destroy(&condr);
pthread_mutex_destroy(&mwrite);
pthread_mutex_destroy(&mread);
return 0;
}
在此先感谢您的帮助!
EDIT:// 在这种情况下我怎样才能避免比赛?
您可以使用一个互斥量和两个条件变量来实现这一点。
reader( ) {
pthread_mutex_lock(&m);
while (!(writers == 0))
pthread_cond_wait(&readersQ, &m);
readers++;
pthread_mutex_unlock(&m);
/* actual read */
pthread_mutex_lock(&m);
if (--readers == 0)
pthread_cond_signal(&writersQ);
pthread_mutex_unlock(&m);
}
writer( ) {
pthread_mutex_lock(&m);
writers++;
while (!((readers == 0) && (active_writers == 0))) {
pthread_cond_wait(&writersQ, &m);
}
active_writers++;
pthread_mutex_unlock(&m);
/* actual write */
pthread_mutex_lock(&m);
writers--;
active_writers--;
if (writers > 0)
pthread_cond_signal(&writersQ);
else
pthread_cond_broadcast(&readersQ);
pthread_mutex_unlock(&m);
}
此实施对 readers 不公平,这意味着如果有作者在写作,readers 将永远没有阅读的选择。这是因为写作比阅读更重要。如果你不这么认为,我也可以提供一个对作者不公平的版本。
reader 将选择只读当 writers 为零时。如果只有一个writer,writer不会为0,reader无法读取。
如果有多个写入者,变量active_writers将确保一次只能写入一个写入者。
编辑
以下是饿死作者的版本。对于 reader,它是相同的代码。
writer( ) {
pthread_mutex_lock(&m);
while(!((readers == 0) &&(writers == 0)))
pthread_cond_wait(&writersQ, &m);
writers++;
pthread_mutex_unlock(&m);
/* actual write */
pthread_mutex_lock(&m);
writers--;
pthread_cond_signal(&writersQ);
pthread_cond_broadcast(&readersQ);
pthread_mutex_unlock(&m);
}