使用读写锁实现线程同步

简介:



读写锁与互斥量类似,但读写锁允许更高的并行性。其特性为:写独占,读共享。


读写锁特性:


  1. 读写锁是“写模式加锁”时,解锁前,所有对该锁加锁的线程都会被阻塞。
  2. 读写锁是“读模式加锁”时,如果线程以读模式对其加锁会成功。如果线程以写模式加锁会阻塞。
  3. 读写锁是“读模式加锁”时,如果有另外线程试图以写模式加锁,读写锁通常会阻塞随后的读模式锁请求,这样可以避免读模式锁长期占用,而等待的写模式锁请求长期阻塞;

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


应用实例:

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

pthread_rwlock_t rwlock;

void *pthread_one(void *arg)
{
    /* 分别测试先上写锁和先上读锁的情况 */

    //pthread_rwlock_wrlock(&rwlock);
    pthread_rwlock_rdlock(&rwlock);

    //puts("wrlock locked first, pthread one!");
    puts("rdlock locked first, pthread one!");

    sleep(2);

    puts("after sleep 2s");

    pthread_rwlock_unlock(&rwlock);
}

void *pthread_two(void *arg)
{
    pthread_rwlock_rdlock(&rwlock);

    puts("got the rdlock, pthread two!");
}

int main()
{
    int i = 0;
    pthread_t id[2];

    /* 读写锁初始化 */
    pthread_rwlock_init(&rwlock, NULL);

    pthread_create(&id[0], NULL, pthread_one, NULL);

    sleep(1);

    pthread_create(&id[1], NULL, pthread_two, NULL);

    for(; i<2; i++)
        pthread_join(id[i], NULL);

    /* 销毁读写锁 */
    pthread_rwlock_destroy(&rwlock);

    return 0;
}

运行结果(两种情况):

参考自:www.aliyun.com/jiaocheng/143521.html

原文地址:https://www.cnblogs.com/GyForever1004/p/9691686.html

时间: 2024-11-04 03:58:01

使用读写锁实现线程同步的相关文章

线程同步——用户模式下线程同步——Slim读写锁实现线程同步

1 //Slim读/写锁实现线程同步 2 SRWlock 的目的和关键段相同:对同一资源进行保护,不让其它线程访问. 3 但是,与关键段不同的是,SRWlock允许我们区分哪些想要读取资源的线程(读取者线程) 4 和哪些想要更新资源值的线程(写入者线程).让所有读取者资源在同一时刻访问共享资源应该是 5 可行的,这是因为仅仅读取资源并不存在破坏数据的风险.只有当写入者线程想要对资源进行更新时才需要同步. 6 这种情况下,写入者线程应该独占资源访问权:任何线程,无论是读取还是写入者线程,都不许访问

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

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

java读写锁实现数据同步访问

锁机制最大的改进之一就是ReadWriteLock接口和它的唯一实现类ReentrantReadWriteLock.这个类有两个锁,一个是读操作锁,另一个是写操作锁.使用读操作锁时可以允许多个线程同时访问,但是使用写操作锁时只允许一个线程进行.在一个线程执行写操作时,其他线程不能够执行读操作. 下面我们将通过范例学习如何使用ReadWriteLock接口编写程序.这个范例将使用ReadWriteLock接口控制对价格对象的访问,价格对象存储了两个产品的价格. 1. 创建一个价格信息类Prices

浅析线程间通信二:读写锁和自旋锁

上文讨论了互斥量和条件变量用于线程的同步,本文将讨论读写锁和自旋锁的使用,并给出了相应的代码和注意事项,相关代码也可在我的github上下载. 读写锁 对于互斥量要么是锁住状态要么是不加锁锁状态,而且一次只有一个线程可以对其加锁,而读写锁对线程的读数据加锁请求和写数据加锁请求进行了区分,从而在某些情况下,程序有更高的并发性.对于读写锁,一次只有一个线程可以占有写模式的读写锁,但是多个线程可以同时占有读模式的读写锁.虽然读写锁的实现各不相同,但当读写锁处于读模式锁住状态时,如果有另外的线程试图以写

Linux同步技术之读写锁

互斥锁试图将想进入临界区的所有线程都阻塞住,但是有时候该临界区会涉及由这些线程共享的一个或多个数据的访问或更新,这时候我们就需要用到读写锁. 系统读写锁的分配规则: (1)只要有没有线程持有给定的读写锁用于写,那么任意数量的线程可以持有该读写锁用于读.(系统规定写锁优先,但是可以更改为读锁优先) (2)仅当没有线程持有某个读写锁用于读或用于写时,才能分配该读写锁用于写. 读写锁用于读称为共享锁,读写锁用于写称为独占锁. 读写锁的获取与释放: int pthread_rwlock_rdlock(p

11.6 线程同步

11.6.1 互斥Example11.6.2 避免死锁Example11.6.3 pthread_mutex_timedlock 函数Example11.6.4Reader-Writer LocksExample11.6.5 带有超时功能的读写锁11.6.6 条件变量Example11.6.7 自旋锁11.6.8 BarriersExample 当多个线程控制流需要共享内存的时候,我们需要确保每一个线程所看到的数据是一致的.如果一个线程使用别的线程不会读取或者修改的数据,那么一致性问题并不会出现

信号量、互斥锁,读写锁和条件变量的区别

信号量强调的是线程(或进程)间的同步:“信号量用在多线程多任务同步的,一个线程完成了某一个动作就通过信号量告诉别的线程,别的线程再进行某些动作(大家都 在sem_wait的时候,就阻塞在那里).当信号量为单值信号量是,也可以完成一个资源的互斥访问.有名信号量:可以用于不同进程间或多线程间的互斥与同步 创建打开有名信号量 sem_t *sem_open(const char *name, int oflag); sem_t *sem_open(const char *name, int oflag

【死磕Java并发】-----J.U.C之读写锁:ReentrantReadWriteLock

此篇博客所有源码均来自JDK 1.8 重入锁ReentrantLock是排他锁,排他锁在同一时刻仅有一个线程可以进行访问,但是在大多数场景下,大部分时间都是提供读服务,而写服务占有的时间较少.然而读服务不存在数据竞争问题,如果一个线程在读时禁止其他线程读势必会导致性能降低.所以就提供了读写锁. 读写锁维护着一对锁,一个读锁和一个写锁.通过分离读锁和写锁,使得并发性比一般的排他锁有了较大的提升:在同一时间可以允许多个读线程同时访问,但是在写线程访问时,所有读线程和写线程都会被阻塞. 读写锁的主要特

多线程编程--5种方法实现线程同步

1:用Interlocked系列函数实现线程同步: 2:用CRITICAL_SECTION及其系列函数实现线程同步: 3:用RTL_SRWLOCK及其系列函数实现线程同步: 4:用事件内核对象实现线程同步: 5:用信号量内核对象实现线程同步:   1:用Interlocked系列函数实现线程同步实例如下: //旋转锁 #include <iostream> using namespace std; #include <process.h> #include <windows.