用读写锁实现--读者写者模型

标签: 读者写者模型 读写锁 自旋锁
14人阅读 评论(0) 收藏 举报
分类:

读者写者模型

读者写者模型是操作系统中的一种同步与互斥机制,与生产者消费者模型类似,但不同的是在生产者消费者模型中,多个读者间没有关系,而且消费者会让临界资源的个数减少,而读者不会改变临界资源的个数
这里写图片描述

读者写者模型应该具备的条件

1.写者是排他性的,即有多个写者的情况下,只有一个写者占有仓库。
2.读者可以一起读,采取并行机制。
3.读者和写者是同步且互斥的,如果读者占有了仓库,则写者不能占有,若写者正在写,则读者不能访问仓库。

读者写者模型的策略

1.读者优先
读者先来读取数据,此时写者处于阻塞状态,当读者读取完数据后且没有了读者时写者才能访问仓库。
2.写者优先
写者先写入数据,此时读者处于阻塞状态,当写者写完数据后且没有写者时读者才能访问仓库。
3.公平情况
写者和读者访问仓库的优先级相等,谁先进入优先级队列谁先访问。

自旋锁与挂起等待锁

1.自旋锁
线程申请资源失败时,它会一直在当前检测锁位置处轮寻锁的状态,来查看资源是否能被申请。不断检测的过程叫做自旋,如读写锁。
2.挂起等待锁
线程申请资源失败时,操作系统将其挂起等待,如互斥锁和二元信号量。

读写锁

什么是读写锁?
读写锁是一种特殊的自旋锁,它把对共享资源的访问者划分为读者和写者,读者只对共享资源进行读访问,写者需对贡献资源进行写操作,这个锁相对于自旋锁而言,能提高并发性。原因是在多处理器系统中,允许同时有多个读者来访问共享资源,最大的读者数量其实为实际的逻辑CPU数。写者是排他性的,一个读写锁可以同时有一个写者或多个读者,但不能同时既有读者又有写者。

读写锁的状态
1.写加锁状态
当处于写加锁状态,在被解锁之前,所有试图对锁进行访问的线程都会被阻塞,通俗来讲,就是“只有自己可以进行写,其他操作都不能进行”。
2.读加锁状态
当处于读加锁状态,所有试图以读模式对这个锁进行访问的线程都可以获得访问权,但是任何以写模式对锁进行访问的线程都会被阻塞,直到所有的线程都释放他们的读状态锁为止。通俗来讲,就是“只要线程是读模式就可以访问”。

读写锁相关函数
1.初始化读写锁&销毁
这里写图片描述
参数:
attr表示初始化读写锁的属性,NULL为默认属性。

2.读加锁函数
这里写图片描述
返回值:成功返回0,失败返回错误码。
注意:因为操作系统对读者数量有限制,所以当我们使用读加锁函数时最好先判断一下返回值。

3.写加锁函数
这里写图片描述
返回值:成功返回0,失败返回错误码。
pthread_rwlock_rdlock加锁失败则被挂起等待,pthread_rwlock_trylock加锁失败不挂起等待采用轮询式等待。

4.解锁函数
这里写图片描述
返回值:成功返回0,失败返回错误码。
对于读加锁和写加锁而言,解锁函数相同。

代码实现读者写者模型:
4个写者线程,6个读者线程。

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

int count;
pthread_rwlock_t rwlock;

//write
void *writer(void *arg){
    int t;
    int i = *(int*)arg;
    free(arg);

    while(1){
        t = count;
        usleep(10000);

        pthread_rwlock_wrlock(&rwlock);
        printf("write:%d:%#X:count=%d ++count=%d\n",i,pthread_self()\
                ,t,count++);
        pthread_rwlock_unlock(&rwlock);
        usleep(50000);
    }
}

//read
void *reader(void *arg){
    int t;
    int i = *(int*)arg;
    free(arg);

    while(1){
        pthread_rwlock_rdlock(&rwlock);
        printf("read:%d:%#X:count=%d\n",i,pthread_self(),count);
        pthread_rwlock_unlock(&rwlock);
        usleep(9000);
    }
}

int main()
{
    int i;
    pthread_t tid[10];
    pthread_rwlock_init(&rwlock, NULL);                                     

    for(i=0;i<4;++i){
        int *p = (int*)malloc(sizeof(int));
        *p = i;
        pthread_create(&tid[i], NULL, writer, (void*)p);
    }

    for(i=0;i<6;++i){
        int *p = (int*)malloc(sizeof(int));
        *p = i;
        pthread_create(&tid[i], NULL, reader, (void*)p);
    }

    for(i=0;i<10;++i){
        pthread_join(tid[i], NULL);
    }

    pthread_rwlock_destroy(&rwlock);

    return 0;
}

运行结果:
这里写图片描述

查看评论

一种读者优先的读写锁的实现

读写锁 rw_lock 互斥锁 mutex 自旋锁 spinlock 条件变量 condition_variable
  • mink2010
  • mink2010
  • 2016-05-24 15:56:54
  • 594

读写锁解决读者与写者问题

读写锁是用来解决读者写者问题的,读操作可以共享,写操作是排他的,读可以有多个在读,写只有唯一个在写,同时写的时候不允许读。 在编写多线程的时候,有一种情况是比较常见的。那就是,有些公共数据修改的机...
  • hj605635529
  • hj605635529
  • 2017-04-12 12:50:29
  • 500

Linux---读者写者模型

一 怎么理解读者写者模型读者写者问题就是在一些程序中,对某些资源的访问会存在两种可能的情况:一种就是写操作,写操作是可以独占资源的,具有排他性;另一种情况就是读操作,在读操作中可以有多个操作并发的去访...
  • blight_888
  • blight_888
  • 2017-06-26 21:14:28
  • 282

读者-写者模型

一.读者-写者模型我们知道在一些程序中存在读者写者问题,就是对某些资源的访问会存在两种可能的情况:一种就是写操作,写操作是可以独占资源的,也就是具有排他性;另一种情况就是读操作,在读操作中可以有多个资...
  • qq_35032155
  • qq_35032155
  • 2017-06-23 00:13:29
  • 307

c语言实现读者写者问题

  • 2009年06月11日 13:34
  • 5KB
  • 下载

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

读者写者的几种实现方法
  • havedream_one
  • havedream_one
  • 2015-07-05 08:13:27
  • 1316

例说读者写者模型

前面我们学习了生产者和消费者模型,想了解一下的可以去看看这篇客: http://blog.csdn.net/bit_clearoff/article/details/55805884什么是读者写者模...
  • bit_clearoff
  • bit_clearoff
  • 2017-02-20 16:22:08
  • 818

linux C++ 多线程 读者写者实现

linux C++ 多线程 读者写者实现: /*readerAndWriter.cpp*/ #include #include #include #include int buf...
  • stone_flower_rain
  • stone_flower_rain
  • 2015-09-15 20:49:04
  • 904

读者写者问题 C语言实现

  • 2010年05月12日 01:05
  • 473KB
  • 下载
    个人资料
    持之以恒
    等级:
    访问量: 1万+
    积分: 1169
    排名: 4万+
    最新评论