线程同步——读写锁

读写锁

读写锁与互斥量类似。也是通过加锁的方式来实现线程之间的数据同步。互斥量的特点是 一次只有一个线程对其加锁。而对于度操作来说,即使有多个线程同时进行读操作是不会 产生冲突的。读写锁便利用了这个特性。它一共有三个状态:读模式下加锁状态,写模式 下加锁状态和不加锁状态。使用的规则如下:

  • 当读写锁是写加锁状态时,在这个锁被解锁之前,所有试图对这个锁加锁的线程都会被阻塞。但是以读方式枷锁的线程是可以操作共享数据的。
  • 当读写锁是读加锁状态时,所有试图以读模式对它进行加锁的线程都可以得到访问权限但是如果线程希望以写模式对此锁进行加锁,它必须阻塞直到所有的线程释放读锁。

读写锁非常适合对数据结构读的次数远大于写的情况。

接口函数

读写锁用 pthread_rwlock_t 数据类型表示。操作读写的函数与互斥量接口函数非常相似:

#include <pthread.h>
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,
const pthread_rwlockattr_t *restrict attr);

int pthread_rwlock_destory(pthread_rwlock_t *rwlock);
                            两者的返回值都是:若成功返回0;否则返回错误编号

读写锁使用之前需要使用 pthread_rwlock_init 函数进行初始化。attr 参数可以设置为 NULL 表示使用默认属性的读写锁。在使用完读写锁之后需要调用 pthread_rwlcok_destory 来释放读写锁的内存。

#include <pthread.h>
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
                            三个函数的返回值都是:若成功返回0;否则返回错误编号

pthread_rwlock_rdlock 函数尝试以读模式加锁,pthread_rwlock_wrlock 函数尝试以写模式加锁。 在获得读写锁之后都可以通过 pthread_rwlock_unlock 函数解锁。

实例

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

int global = 0;
pthread_rwlock_t rwlock = PTHREAD_MUTEX_INITIALIZER;

void *fun1(void *arg)
{
    int i = 0;
    for (; i < 50; i++)
    {
        pthread_rwlock_wrlock(&rwlock);
        global += 1;
        printf("pthread 1 write %d\n", global);
        sleep(1);
        pthread_rwlock_unlock(&rwlock);
    }
    pthread_exit((void*)1);
}

void *fun2(void *arg)
{
    int i = 0;
    for (; i < 10; i++)
    {
        pthread_rwlock_rdlock(&rwlock);
        printf("pthread 2 read the global is %d\n", global);
        pthread_rwlock_unlock(&rwlock);
    }
    pthread_exit((void *)2);
}

int main()
{

    pthread_t tid1, tid2;

    if (pthread_create(&tid1, NULL, fun1, NULL) != 0)
        return -1;
    if (pthread_create(&tid2, NULL, fun2, NULL) != 0)
        return -1;

    sleep(4);
    return 0;
}

时间: 2024-10-06 00:27:34

线程同步——读写锁的相关文章

linux系统编程:线程同步-读写锁(rwlock)

线程同步-读写锁(rwlock) 读写锁 读写锁是互斥量的细化:显然,只有对全局资然进行写入操作时,才需要同步:在对全局资然进行读取操作时,是不需要锁的. 相关函数 pthread_rwlock_t //读写锁类型 pthread_rwlock_init //初始化 pthread_rwlock_destroy //销毁锁 pthread_rwlock_rdlock //获取读锁 pthread_rwlock_wrlock //获取写锁 pthread_rwlock_tryrdlock pthr

“全栈2019”Java多线程第四十二章:获取线程与读写锁的保持数

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多线程第四十二章:获取线程与读写锁的保持数 下一章 "全栈2019"Java多线程第四十三章:查询是否有线程在等待读写锁 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复&quo

Linux:使用读写锁使线程同步

基础与控制原语 读写锁 与互斥量类似,但读写锁允许更高的并行性.其特性为:写独占,读共享. 读写锁状态: 一把读写锁具备三种状态: 1. 读模式下加锁状态 (读锁) 2. 写模式下加锁状态 (写锁) 3. 不加锁状态 读写锁特性:     读写锁是"写模式加锁"时, 解锁前,所有对该锁加锁的线程都会被阻塞. 读写锁是"读模式加锁"时, 如果线程以读模式对其加锁会成功:如果线程以写模式加锁会阻塞. 读写锁是"读模式加锁"时, 既有试图以写模式加锁的

Java 线程锁机制 -Synchronized Lock 互斥锁 读写锁

synchronized 是互斥锁: lock 更广泛,包含了读写锁 读写锁特点: 1)多个读者可以同时进行读2)写者必须互斥(只允许一个写者写,也不能读者写者同时进行)3)写者优先于读者(一旦有写者,则后续读者必须等待,唤醒时优先考虑写者) 互斥锁特点: 一次只能一个线程拥有互斥锁,其他线程只有等待 所谓互斥锁, 指的是一次最多只能有一个线程持有的锁. 在jdk1.5之前, 我们通常使用synchronized机制控制多个线程对共享资源的访问. 而现在, Lock提供了比synchronize

pthread_rwlock_t读写锁函数说明

读写锁 索引: 初始化一个读写锁pthread_rwlock_init 读锁定读写锁      pthread_rwlock_rdlock 非阻塞读锁定 pthread_rwlock_tryrdlock 写锁定读写锁      pthread_rwlock_wrlock 非阻塞写锁定      pthread_rwlock_trywrlock 解锁读写锁         pthread_rwlock_unlock 释放读写锁         pthread_rwlock_destroy 读写锁是

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

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

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

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

Java并发编程之重入锁与读写锁

重入锁 重入锁,顾名思义,就是支持重进入的锁,它表示该锁能够支持一个线程对资源的重复加锁.重进入是指任意线程在获取到锁之后能够再次获取该锁而不会被锁阻塞,该特性的实现需要解决以下两个问题. 1.线程再次获取锁.锁需要去识别获取锁的线程是否为当前占据锁的线程,如果是,则再次成功获取. 2.锁的最终释放.线程重复n次获取了锁,随后在第n次释放该锁后,其他线程能够获取到该锁.锁的最终释放要求锁对于获取进行计数自增,计数表示当前锁被重复获取的次数,而锁被释放时,计数自减,当计数等于0时表示锁已经成功释放

C#学习笔记---线程同步:互斥量、信号量、读写锁、条件变量

http://www.cnblogs.com/maxupeng/archive/2011/07/21/2112282.html 一.互斥量(mutex) 互斥量本质上是一把锁,在访问共享资源前对互斥量进行加锁,在访问完成后释放互斥量上的锁. 对互斥量进行加锁以后,任何其它试图再次对互斥量加锁的线程将会被阻塞直到当前线程释放该互斥锁.如果释放互斥锁时有多个线程阻塞,所有在该互斥锁上的阻塞线程都会变成可运行状态,第一个变为运行状态的线程可以对互斥量加锁,其它线程将会看到互斥锁依然被锁住,只能回去再次