读者写者多线程

读者写者

1.描述操作系统中“读者-写者”问题,理解问题的本质,提交你理解或查找到的文本资料

读者写者问题可分为读者优先读写公平写者优先三种,无论是其中哪一种,在没有程序占用临界区时,读者与写者之间的竞争都是公平的,所谓的不公平(优先)是在读者优先和写者优先中,优先方只要占有了临界区,那么之后所有优先方的程序便占有了临界区的主导权,所谓的优先可以理解为优先方在占有临界区后便可以对临界区进行“垄断”

(1)读者优先

即使写者发出了请求写的信号,但是只要还有读者在读取内容,就还允许其他读者继续读取内容,直到所有读者结束读取,才真正开始写。

到达次序:“读——写——读”

实际执行次序:“读——读——写”

(2)读写公平

读者和写者的地位是完全平等的,即无论是读者还是写者,都按它们到达的时间先后决定优先次序。

到达次序:“写——读——写”或“读——写——读”

实际执行次序:“写——读——写”或“读——写——读”

(3)写者优先

如果有写者申请写文件,在申请之前已经开始读取文件的可以继续读取,但是如果再有读者申请读取文件,则不能够读取,只有在所有的写者写完之后才可以读取。

到达次序:“写——读——写”

实际执行次序:“写——写——读”

2.代码实现

读者优先

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <unistd.h>

#define N 5

int count=0,a=5,b=5;
int r[N]={0,1,2,3,4};
sem_t wmutex,rmutex;


void delay()
{
int time = rand() % 10 + 1;         //随机使程序睡眠0点几秒          
usleep(time * 100000);
}

void Reader(void *arg)
{
int i=*(int *)arg;
while(a>0)
{
  a--;
  delay();
      sem_wait(&rmutex);
      if(count==0)
        sem_wait(&wmutex);
      count++;
      sem_post(&rmutex);

      printf("Reader%d is reading!\n",i);
      printf("Reader%d reads end!\n",i);
     
      sem_wait(&rmutex);
      count--;
      if(count==0)
        sem_post(&wmutex);
      sem_post(&rmutex);
  }
}

void Writer()
{
while(b>0)
  {
  b--;
  delay();
      sem_wait(&wmutex);
 
  printf("writer is writing!\n");
      printf("writer writes end!\n");
 
      sem_post(&wmutex);
  }
}

int main()
{
int i;
pthread_t writer,reader[N];
srand((unsigned int)time(NULL));

sem_init(&wmutex,0,1);//互斥锁初始化
sem_init(&rmutex,0,1);

for(i=0;i<5;i++)//创建线程
{
pthread_create(&reader[i],NULL,(void *)Reader,&r[i]);
}

pthread_create(&writer,NULL,(void *)Writer,NULL);

pthread_join(writer,NULL);//线程等待

sem_destroy(&rmutex);   //互斥锁的销毁
sem_destroy(&wmutex);  

return 0;
}

截图:

 

写者优先

代码:

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <unistd.h>

#define N 5

int readcount=0,writecount=0,a=5,b=2;
int r[N]={0,1,2,3,4};
int w[N]={0,1};
sem_t wmutex,rmutex,mutex1,num;


void delay()
{
int time = rand() % 10 + 1;         //随机使程序睡眠0点几秒          
usleep(time * 100000);
}

void Reader(void *arg)
{
int i=*(int *)arg;
while(a>0)
{
  a--;
  delay();//延迟
 
//进入共享文件前的准备
  sem_wait(&num);//在无写者进程时进入
      sem_wait(&rmutex);//与其他读者进程互斥的访问readcount
      if(readcount==0)
      sem_wait(&mutex1);//与写者进程互斥的访问共享文件
      readcount++;
      sem_post(&rmutex);
      sem_post(&num);

//reader
      printf("Reader%d is reading!\n",i);
      printf("Reader%d reads end!\n",i);
     
      //退出共享文件后的处理
      sem_wait(&rmutex);
      readcount--;
      if(readcount==0)
      sem_post(&mutex1);
      sem_post(&rmutex);
  }
}

void Writer(void *arg)
{
int i=*(int *)arg;
while(b>0)
  {
  b--;
  delay();
 
  //进入共享文件前的准备
  sem_wait(&wmutex);//保证多个写者进程能够互斥使用writecount
  writecount++;
  if(writecount==1)
  sem_wait(&num);//用于禁止读者进程
  sem_post(&wmutex);
 
  //writer
      sem_wait(&mutex1);//与其他所有进程互斥的访问共享文件
  printf("writer%d is writing!\n",i);
      printf("writer%d writes end!\n",i);
  sem_post(&mutex1);
     
      //退出共享文件后的处理
      sem_wait(&wmutex);
  writecount--;
  if(writecount==0)
  sem_post(&num);
  sem_post(&wmutex);
  }
}

int main()
{
int i;
pthread_t writer[N],reader[N];
srand((unsigned int)time(NULL));

sem_init(&wmutex,0,1);//互斥锁初始化
sem_init(&rmutex,0,1);
sem_init(&mutex1,0,1);
sem_init(&num,0,1);

for(i=0;i<5;i++)//创建线程
{
pthread_create(&reader[i],NULL,(void *)Reader,&r[i]);
}

for(i=0;i<2;i++)//创建线程
{
pthread_create(&writer[i],NULL,(void *)Writer,&w[i]);
}

for(i=0;i<2;i++)//等待线程
{
pthread_join(writer[i],NULL);
}

for(i=0;i<5;i++)//等待线程
{
pthread_join(reader[i],NULL);
}

sem_destroy(&rmutex);   //互斥锁的销毁
sem_destroy(&wmutex);  
sem_destroy(&mutex1);
sem_destroy(&num);

return 0;
}

截图:

 

读写公平

代码:

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <unistd.h>

#define N 5

int readcount=0,a=5,b=5;
int r[N]={0,1,2,3,4};
sem_t wmutex,rmutex,queue;


void delay()
{
int time = rand() % 10 + 1;         //随机使程序睡眠0点几秒          
usleep(time * 100000);
}

void Reader(void *arg)
{
int i=*(int *)arg;
while(a>0)
{
  a--;
  delay();
 
sem_wait(&queue); //让写者进程排队,读写进程具有相同的优先级
      sem_wait(&rmutex); //与其他读者进程互斥的访问readcount
      if(readcount==0) //最开始的时候readcount=0
      sem_wait(&wmutex); //与写者进程互斥的访问共享文件
      readcount++;
      sem_post(&rmutex);
sem_post(&queue); //使得写者进程进入准备状态

//Reader
      printf("Reader%d is reading!\n",i);
      printf("Reader%d reads end!\n",i);
     
      sem_wait(&rmutex);
      readcount--;
      if(readcount==0)
        sem_post(&wmutex);
      sem_post(&rmutex);
  }
}

void Writer()
{
while(b>0)
  {
  b--;
  delay();
 
  sem_wait(&queue);
      sem_wait(&wmutex);
 
  printf("writer is writing!\n");
      printf("writer writes end!\n");
 
      sem_post(&wmutex);
      sem_post(&queue);
  }
}

int main()
{
int i;
pthread_t writer,reader[N];
srand((unsigned int)time(NULL));

sem_init(&wmutex,0,1);//互斥锁初始化
sem_init(&rmutex,0,1);
sem_init(&queue,0,1);

for(i=0;i<5;i++)//创建线程
{
pthread_create(&reader[i],NULL,(void *)Reader,&r[i]);
}

pthread_create(&writer,NULL,(void *)Writer,NULL);

pthread_join(writer,NULL);//线程等待

sem_destroy(&rmutex);   //互斥锁的销毁
sem_destroy(&wmutex);  
sem_destroy(&queue);

return 0;
}

截图:

 

 

 

 

 



posted @ 2022-11-10 19:19  20201322陈俊池  阅读(134)  评论(0编辑  收藏  举报