多线程同步之读者写者问题

问题定义:

现有一块共享内存,多个读进程和多个写进程。多个读进程可以同时读,但是当有一个写进程正在写时,其他任何读进程或写进程都不能执行。

该问题有3种变种。第一种称为“读者优先”(readers-preference)。在此情况下,只要有进程在读,写进程就得等待。

实现如下:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define M 6        //number of readers
#define N 2        //number of writers
int readCount = 0; //current number of readers
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;    //用于互斥地修改readCount变量
pthread_mutex_t rw = PTHREAD_MUTEX_INITIALIZER;      //用于读、写以及写、写之间的互斥

void* write(void *arg)
{
    pthread_mutex_lock(&rw);
    printf("writer %d is writing\n", arg);
    sleep(1);
    printf("writer %d is leaving\n", arg);
    pthread_mutex_unlock(&rw);
}

void* read(void *arg)
{
    pthread_mutex_lock(&mutex);
    if (readCount == 0)
        pthread_mutex_lock(&rw);
    ++readCount;
    pthread_mutex_unlock(&mutex);

    printf("reader %d is reading\n", arg);
    sleep(1);
    printf("reader %d is leaving\n", arg);

    pthread_mutex_lock(&mutex);
    --readCount;
    if (readCount == 0)
        pthread_mutex_unlock(&rw);
    pthread_mutex_unlock(&mutex);
}

int main()
{
    pthread_t readers[M], writers[N];
    int i;
    for (i = 0; i < M; ++i)
        pthread_create(&readers[i], NULL, read, (void*)i);
    for (i = 0; i < N; ++i)
        pthread_create(&writers[i], NULL, write, (void*)i);
    sleep(10);
    return 0;
}

这种情况下,容易造成写者饿死现象。

时间: 2024-08-12 13:51:46

多线程同步之读者写者问题的相关文章

秒杀多线程第十一篇 读者写者问题

与上一篇<秒杀多线程第十篇 生产者消费者问题>的生产者消费者问题一样,读者写者也是一个非常著名的同步问题.读者写者问题描述非常简单,有一个写者很多读者,多个读者可以同时读文件,但写者在写文件时不允许有读者在读文件,同样有读者在读文件时写者也不去能写文件. 上面是读者写者问题示意图,类似于生产者消费者问题的分析过程,首先来找找哪些是属于“等待”情况. 第一.写者要等到没有读者时才能去写文件. 第二.所有读者要等待写者完成写文件后才能去读文件. 找完“等待”情况后,再看看有没有要互斥访问的资源.由

转---秒杀多线程第十一篇 读者写者问题

与上一篇<秒杀多线程第十篇 生产者消费者问题>的生产者消费者问题一样,读者写者也是一个非常著名的同步问题.读者写者问题描述非常简单,有一个写者很多读者,多个读者可以同时读文件,但写者在写文件时不允许有读者在读文件,同样有读者在读文件时写者也不去能写文件. 上面是读者写者问题示意图,类似于生产者消费者问题的分析过程,首先来找找哪些是属于“等待”情况. 第一.写者要等到没有读者时才能去写文件. 第二.所有读者要等待写者完成写文件后才能去读文件. 找完“等待”情况后,再看看有没有要互斥访问的资源.由

秒杀多线程第十一篇 读者写者问题(续)

java实现: 本问题的关键是读者写者之间的同步问题,尤其使用java来操作. 1.等待读者,使用CountDownLatch mReaderLatch, 但是CountDownLatch只能使用一次,所以需要每次都new 一个. 或者可以考虑使用semaphore代替,但是semaphore需要acquire(READ_THREAD_SIZE)才能等待所有读者线程结束. 2.等待写入操作.使用semaphore来控制, mWriteSema.release(READ_THREAD_SIZE);

转---秒杀多线程第十四篇 读者写者问题继 读写锁SRWLock

在<秒杀多线程第十一篇读者写者问题>文章中我们使用事件和一个记录读者个数的变量来解决读者写者问题.问题虽然得到了解决,但代码有点复杂.本篇将介绍一种新方法——读写锁SRWLock来解决这一问题.读 写锁在对资源进行保护的同时,还能区分想要读取资源值的线程(读取者线程)和想要更新资源的线程(写入者线程).对于读取者线程,读写锁会允许他们并发的 执行.当有写入者线程在占有资源时,读写锁会让其它写入者线程和读取者线程等待.因此用读写锁来解决读者写者问题会使代码非常清晰和简洁. 下面就来看看如何使用读

Linux多线程实践(6) --Posix读写锁解决读者写者问题

Posix读写锁 int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr); int pthread_rwlock_destroy(pthread_rwlock_t *rwlock); int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); int pthread_rwlock_wrlock(pthre

多线程---读者写者问题

有几种思路 1.利用信号量来实现读者写者的互斥(读者和读者之间是并行的) public class ReaderAndWriter { private static AtomicInteger reader = new AtomicInteger(); private static AtomicInteger blocked = new AtomicInteger(); //用来对读者写者互斥 private static Semaphore ws = new Semaphore(1,true)

多线程面试题系列(14):读者写者问题继 读写锁SRWLock

在第十一篇文章中我们使用事件和一个记录读者个数的变量来解决读者写者问题.问题虽然得到了解决,但代码有点复杂.本篇将介绍一种新方法--读写锁SRWLock来解决这一问题.读写锁在对资源进行保护的同时,还能区分想要读取资源值的线程(读取者线程)和想要更新资源的线程(写入者线程).对于读取者线程,读写锁会允许他们并发的执行.当有写入者线程在占有资源时,读写锁会让其它写入者线程和读取者线程等待.因此用读写锁来解决读者写者问题会使代码非常清晰和简洁. 下面就来看看如何使用读写锁,要注意编译读写锁程序需要V

读者写者模式

在编写多线程的时候,有一种情况是比较常见的.那就是,有些公共数据修改的机会比较少.相较改写,它们读的机会反而多的多. 读者写者模式:三种关系,两类人,一个场所 三种关系: 读者与读者:无关系 写者与写者:互斥 读者与写者:同步与互斥 两类人:读者,写者 一个场所:同一临界资源(数据) 自旋锁:如果所等待条件不满足,不挂起,一直申请锁.适宜某个线程占用锁时间较短. 当不断有多个读者准备读时,如果有写者到来,此时应该当前读者读完后,提高写者优先级,下个进入临界区的是写者.---------写者优先,

Java实现生产者消费者问题与读者写者问题

摘要: Java实现生产者消费者问题与读者写者问题 1.生产者消费者问题 生产者消费者问题是研究多线程程序时绕不开的经典问题之一,它描述是有一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品.解决生产者/消费者问题的方法可分为两类:(1)采用某种机制保护生产者和消费者之间的同步:(2)在生产者和消费者之间建立一个管道.第一种方式有较高的效率,并且易于实现,代码的可控制性较好,属于常用的模式.第二种管道缓冲区不易控制,被传输数据对象不易于封装等,实用性不强. 同步问题核心在