读者---写者问题

                                           经典进程同步与互斥问题

读者---写者问题

1.问题描述

一个数据对象若被多个并发进程所共享,且其中一些进程只要求读该数据对象的内容,而另一些

进程则要求写操作,对此,把只想读的进程称为“读者”,而把要求写的进程称为“写者”。在

读者--写着问题中,任何时刻要求“写者”最多只允许有一个,而读者则允许有多个。因为多个

读者的行为互不干扰,他们只是读数据,而不改变数据对象的内容,而写者则不同,他们要改变数据对象的内容,如果他们同时操作,则数据对象的内容将会改变的不可知。所以对共享资源的读写操作的限制条件是:

1>允许任意多的读进程同时读;

2>一次只允许一个写进程写操作;

3>如果有一个写进程正在进行写操作,禁止任何读进程进行读操作。

2.用信号量解决读者--写着问题

为了解决“写着与写着”和“写着与第一个读者”的互斥问题即可,为此引入互斥信号量Wmutex。

为了记录谁是第一个读者,可以用一个全局整型变量Rcount做一个计数器。而在解决问题的过程中,由于使用了全局变量Rcount,该变量又是一个临界资源,对于他的访问仍需互斥进行,所以需要

一个互斥信号量Rmutex。

3.思考问题

对于读者---写者问题,有以下三种策略。

1>读者优先。即当读者进行读时,后续的写者必须等待,直到所有的读者均离开后,写着才可进入。

2>写者优先。即当一个写者到来时,只有那些已经获得授权允许读的进程才允许完成他们的操作,

写者之后到来的读者将被推迟,直到写者完成。在该策略中,如果有一个不可中断的连续的写者,

读者进程会被无限期的推迟。

3>公平策略。以上两种策略,读者或写进程中一个对一个有绝对的优先权,Hoare提出了一种更公平

的策略,由如下规则定义。

规则1:在一个读序列中,如果有写者在等待,那么就不允许有新的读者开始执行。

规则2:在一个写操作结束时,所有等待的读者应该比下一个写者有更高的优先权。

对于公平策略,又如何解决呢?

 

#include <pthread.h>

#include <semaphore.h>

#include <sys/types.h>

#include <stdio.h>

#include <unistd.h>

#include<stdlib.h>

int Rcount=0,num=0;   //被保护的全局变量

sem_t Wmutex,Rmutex,mutex;

void* read1(void *arg)

{

 sem_wait(&mutex);

 sem_wait(&Rmutex);//读者到来

 if(Rcount==0)

 {

   printf("第一个读者到来\n");

   sem_wait(&Wmutex);

 }

 Rcount=Rcount+1;//读者数目

 sem_post(&Rmutex);

 sem_post(&mutex);

 printf("线程%lu正在进行读数据%d\n",pthread_self(),num);

 sleep(1);

 sem_wait(&Rmutex);//读者阅读结束

 Rcount=Rcount-1;

 if(Rcount==0)//所有的读者阅读结束

 {

     sem_post(&Wmutex);

     printf("读者全部退出\n");

 }

 sem_post(&Rmutex);

}

 

void* write1(void *arg)

{

 sem_wait(&mutex);

 sem_wait(&Wmutex);

 num=num+1;

 printf("线程%lu正在进行写数据%d\n",pthread_self(),num);

 sem_post(&Wmutex);

 sem_post(&mutex);

}

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

{     int i=0;

      int j=3;

      pthread_t tid[5];

      sem_init(&Wmutex,0,1);  

      sem_init(&Rmutex,0,1);  

      sem_init(&mutex,0,1);  

      while(i<=2)

        {

           if((pthread_create(&tid[i],NULL,read1,NULL))!=0)

                {

                        printf("can't create pthread.\n");

                       exit(0);

                }

                i++;

        }

        while(j<=4)

        {

           if((pthread_create(&tid[j],NULL,write1,NULL))!=0)

                {

                        printf("can't create pthread.\n");

                       exit(0);

                }

                j++;

        }

      for(i=0;i<5;i++)

        pthread_join(tid[i],NULL); 

      sem_destroy(&Wmutex); 

      sem_destroy(&Rmutex); 

      printf("程序运行结束\n");

      return 0;

}
写者优先

 

#include <pthread.h>

#include <semaphore.h>

#include <sys/types.h>

#include <stdio.h>

#include <unistd.h>

#include<stdlib.h>

int Rcount=0,num=0;   //被保护的全局变量

sem_t Wmutex,Rmutex;

void* read1(void *arg)

{

 sem_wait(&Rmutex);//读者到来

 if(Rcount==0)

 {

   printf("第一个读者到来\n");

   sem_wait(&Wmutex);

 }

 Rcount=Rcount+1;//读者数目

 sem_post(&Rmutex);

 printf("线程%lu正在进行读数据%d\n",pthread_self(),num);

 sleep(1);

 sem_wait(&Rmutex);//读者阅读结束

 Rcount=Rcount-1;

 if(Rcount==0)//所有的读者阅读结束

 {

     sem_post(&Wmutex);

     printf("读者全部退出\n");

 }

 sem_post(&Rmutex);



}

 

void* write1(void *arg)

{

 sem_wait(&Wmutex);

 num=num+1;

 printf("线程%lu正在进行写数据%d\n",pthread_self(),num);

 sem_post(&Wmutex);

}

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

{     int i=0;

      int j=3;

      pthread_t tid[5];

      sem_init(&Wmutex,0,1);  // 空闲的

      sem_init(&Rmutex,0,1);  // 忙的

      while(i<=2)

        {

           if((pthread_create(&tid[i],NULL,read1,NULL))!=0)

                {

                        printf("can't create pthread.\n");

                       exit(0);

                }

                i++;

        }

        while(j<=4)

        {

           if((pthread_create(&tid[j],NULL,write1,NULL))!=0)

                {

                        printf("can't create pthread.\n");

                       exit(0);

                }

                j++;

        }

      for(i=0;i<5;i++)

        pthread_join(tid[i],NULL); 

      sem_destroy(&Wmutex); 

      sem_destroy(&Rmutex); 

      printf("程序运行结束\n");

      return 0;

}
读者优先

 

你可能感兴趣的:(问题)