reader-writer accessing multiple readers

匿名 (未验证) 提交于 2019-12-03 02:34:02

问题:

I have a few problems I can't solve in implementing WRITER-READER problem in UNIX. First one is that I have no idea, how can I modify the code to work like threads are always calling to enter reading room. For example, when a writer is in the reading room, readers are waiting to access the reading room. When writer is escaping the reading room and readers are entering the reading room, he still is waiting for his chance. The second one is that I have no idea how to modify the code to allow a few readers to enter the reading room. In my code only one thread can be in the same time in the reading room. The third one is, how to recognize if writer or reader is starving? Which one is starving in my code?

Here is the code:

#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; } 

Thanks in advance for your help!

EDIT:// How can I avoid race in this case?

回答1:

you could use one mutex and two conditional variables to implement this.

`

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); } 

`

This implementation is unfair to the readers, which means if there is a writer writing, readers will never get a choice to read. This is because writing is more important than reading. If you don't think so, I can also provide a version which is unfair to writers.

The reader will get choice to read only when writers is equal to zero. If there is a single writer, writer will not be zero and reader cannot read.

If there are multiple writers, the variable active_writers will make sure that only one writer could write at a time.

EDIT

below is the version starve writers. For reader, it is the same code.

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); } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!