进程(线程)间的同步互斥问题(五) 读者-作者问题

问题描述:


用读者和写者来模拟并行计算的过程:

  • 读者在读的时候,写者不能写,必须等到读者读完
  • 多个读者可以读一本书
  • 同时只能一个作者在写
  • 在写的时候,读者不能读

问题分析:


  • 作品是共享的资源,作者和读者要竞争这个资源,要避免决策导致某一方被饿死(长时间竞争不到资源)。
  • 共享资源是简单的只能有一个人能使用,而是在读者读的时候能够多人同时共享资源,在写者占有资源的时候,只能有一个写者持有这个资源

基本思路:

  • 最基本的想法使采取一般的进程同步互斥问题的思路,也就是信号量的最基本的用法:
    • 定义一个互斥量mutex,与作品资源绑定,每次只能有一个进程(线程)利用这个资源
    • 但是这种方法明显忽略一个特点,就是读者处于浏览作品的时候,是可以多个读者同时,这种方法明显会造成资源的浪费
  • 然后考虑的读者优先的方案:
    • 定义一个互斥量mutex与作品资源绑定,但是不再限定每次只有一个进程(线程)利用这个资源,采取的策略是定义一个numReader的共享的变量来记录当前读者个数(既然是一个共享的变量,那么自然需要一个互斥量,来保证同步过程中同时只有一个进程在修改它)。
    • 有一个新的读者的时候首先查看当前读者的总数
      • 如果新来的读者不是第一读者,那么他不需要检查互斥锁,直接可以参与到阅读中
      • 如果新来的读者是第一读者,那么他需要检查互斥锁,如果锁住了,说明有作者在修改,那么等待作者写完再读,先睡觉,如果没锁住,那么开始阅读,并且将锁锁住
    • 写者的操作就是简单地检查互斥锁
    • 那么这种方案,因为是写者优先,所以可能导致作者饿死
  • 再考虑写者优先的解决方案:
    • 定义一个互斥量mutex与作品资源绑定,但是不再限定每次只有一个进程(线程)利用这个资源。
    • 定义rdMutex来绑定记录读者数量的互斥量,定义rwMutex来记录当前是否有写者在等着写或者正在写。
    • 那么读者在每次阅读前,都要检查是否有写者要写,如果有,那么他先睡觉,等写者写完他才开始写,如果一直有写者,那么他可能饿死
    • 这种方案其他的操作与写者优先的无异,但是这种做法已经有很稳定和高效的并行性

代码如下:


  • 读者优先的读者-写者问题解决方案:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>

#define p(x) sem_wait(&x)
#define v(x) sem_post(&x)
#define MAX 20

int numReader;
sem_t mutex,rdMutex;

void init ( )
{
    numReader = 0;
    sem_init ( &mutex , 0 , 1 );
    sem_init ( &rdMutex , 0 , 1 );
}

void* reader ( void* arg )
{
    int* p = (int*)arg;
    int x = *p;
    p(rdMutex);
    if ( numReader == 0 )
        p(mutex);
    numReader++;
    v(rdMutex);
    printf ( "The %dth reader reading....\n" , x );
    sleep(2);
    p(rdMutex);
    numReader--;
    if ( numReader == 0 )
        v(mutex);
    v(rdMutex);
}

void* writer ( void* arg )
{
    int*p = (int*)arg;
    int x = *p;
    p(mutex);
    printf ( "The %dth writer editing...\n" , x );
    sleep(3);
    v(mutex);
}

int main( )
{
    init ();
    int i,j=1;
    pthread_t rid[MAX];
    pthread_t wid[MAX];
    int rid1[MAX];
    int wid1[MAX];
    for ( i = 0 ; i < MAX ;i ++ )
    {
        rid1[i] = i;
        wid1[i] = i;
        pthread_create ( &rid[i] , NULL , reader , &rid1[i] );
        pthread_create ( &wid[i] , NULL , writer , &wid1[i] );
        sleep(2);
    }
    for ( i = 0 ; i < MAX ;i ++ )
    {
        pthread_join ( rid[i] , NULL );
        pthread_join ( wid[i] , NULL );
    }
}
  • 写者优先的读者-写者问题解决方案
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <semaphore.h>
#include <pthread.h>

#define MAX 20
#define p(x) sem_wait(&x)
#define v(x) sem_post(&x)

int numReader;
sem_t rdMutex,wtMutex,mutex;

void init ( )
{
    numReader = 0;
    sem_init ( &rdMutex , 0 , 1 );
    sem_init ( &wtMutex , 0 , 1 );
    sem_init ( &mutex , 0 , 1 );
}

void* reader ( void* arg )
{
    int *p = (int*)arg;
    int x = *p;
    p(wtMutex);
    p(rdMutex);
    if ( numReader == 0 )
        p(mutex);
    numReader++;
    v(rdMutex);
    v(wtMutex);
    printf ( "The %dth reader reading....\n" , x );
    sleep(2);
    p(rdMutex);
    numReader--;
    if ( numReader == 0 )
        v(mutex);
    v(rdMutex);
}

void* writer ( void* arg )
{
    int *p = (int*)arg;
    int x = *p;
    p(wtMutex);
    p(mutex);
    printf ( "The %dth writer editing....\n" , x );
    sleep(4);
    v(mutex);
    v(wtMutex);
}

int main ( )
{
    init ();
    pthread_t rid[MAX];
    pthread_t wid[MAX];
    pthread_t rid1[MAX];
    pthread_t wid1[MAX];
    int i;
    for ( i = 0 ; i < MAX ; i++ )
    {
        rid1[i] = wid1[i] = i;
        pthread_create ( &rid[i] , NULL , reader , &rid1[i] );
        pthread_create ( &wid[i] , NULL , writer , &wid1[i] );
        sleep(1);
    }
    for ( i = 0 ; i < MAX ; i++ )
    {
        pthread_join ( rid1[i] , NULL );
        pthread_join ( wid1[i] , NULL );
    }
}
  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值