【Linux C/C++ 线程同步 】Linux API 读写锁的编程使用

简介: 【Linux C/C++ 线程同步 】Linux API 读写锁的编程使用

读写锁介绍

读写锁比mutex有更高的适用性,可以多个线程同时占用读模式的读写锁,但是只能一个线程占用写模式的读写锁。

  • 当读写锁是写加锁状态时,在这个锁被解锁之前,所有试图对这个锁加锁的线程都会被阻塞;
  • 当读写锁在读加锁状态时,所有试图以读模式对它进行加锁的线程都可以得到访问权,但是以写模式对它进行枷锁的线程将阻塞;
  • 当读写锁在读模式锁状态时,如果有另外线程试图以写模式加锁,读写锁通常会阻塞随后的读模式锁请求,这样可以避免读模式锁长期占用,而等待的写模式锁请求长期阻塞;

读写锁使用场景

读写锁适用对数据结构进行读的次数比写的次数多的情况下,因为可以进行读锁共享。而互斥锁通常用于读写串行。

读写锁相关接口函数

  • 初始化读写锁
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);
//使用互斥变量之前必须初始化

参数:

rwlock:读写锁

attr:为NULL时,表示默认属性

返回值:

    若成功,返回0

    若失败,返回出错编号

  • 销毁读写锁
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
//在释放他们底层的内存之前必须摧毁

返回值:

    若成功,返回0

    若失败,返回出错编号

  • 读加锁和写加锁
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

    若失败,返回出错编号

  • 非阻塞获得读锁和写锁
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
 
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);

返回值:

    若成功,返回0

    若失败,返回出错编号

  • 带有超时的读写锁
int pthread_rwlock_timedwrlock(pthread_rwlock_t *restrict rwlock,const struct timespec *restrict abs_timeout);
 
int pthread_rwlock_timedrdlock(pthread_rwlock_t *restrict rwlock,const struct timespec *restrict abs_timeout);
//使应用程序获取读写锁时避免永久阻塞状态。

参数:

abs_timeout:指向timespec结构,指定线程应该停止阻塞的时间。

返回值:

    若成功,返回0

    若失败,返回出错编号

  • 初始化/销毁读写锁属性
int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);
//将使用实现定义的所有属性的默认值初始化读写锁属性对象attr。
//如果指定已初始化的attr属性对象,则结果未定义。
 
int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr);
//销毁读写锁属性对象。

在读写锁属性对象用于初始化一个或多个读写锁之后,影响属性对象(包括破坏)的任何函数都不会影响任何先前初始化的读写锁。

返回值:

    若成功,返回0

    若失败,返回出错编号

  • 获取/设置读写锁属性对象的进程共享属性
int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *restrict attr, int *restrict pshared);
//从attr引用的初始化属性对象中获取进程共享属性的值。
//将attr的进程共享属性的值存储到由pshared参数引用的对象中。
 
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr,int pshared);
//在attr引用的初始化属性对象中设置进程共享属性。

参数:

进程共享属性应设置为 PTHREAD_PROCESS_SHARED 以允许任何可访问读写锁定分配的内存的线程对读写锁操作,即使读写锁分配在内存中这是由多个进程共享的。

如果进程共享属性为 PTHREAD_PROCESS_PRIVATE 则读写锁只能在与初始化读写锁的线程相同的进程内创建的线程进行操作;

如果不同进程的线程尝试对这样的读写锁进行操作,则行为是未定义的。进程共享属性的默认值应为 PTHREAD_PROCESS_PRIVATE

返回值:

    成功 ,返回 0

    失败 ,返回 出错编号

使用示例

  • 读写锁简单使用代码段
//创建读写锁 
pthread_rwlock_t lock;
pthread_rwlock_init(&lock,NULL);
int data;
/** 写端线程  **/
     //加写锁
    pthread_rwlock_wrlock(&lock);
    data++;
    printf("==write:%lu,%d\n",pthread_self(),data);
    //解锁
    pthread_rwlock_unlock(&lock);
    sleep(1);
/** 读端线程     **/
    //加读锁
    pthread_rwlock_rdlock(&lock);
    printf("==read:%lu,%d\n",pthread_self(),data);
    pthread_rwlock_unlock(&lock);
    sleep(1);
//释放读写锁资源
pthread_rwlock_destroy(&lock);


目录
相关文章
|
13天前
|
Java 程序员 开发者
深入理解Java并发编程:线程同步与锁机制
【4月更文挑战第30天】 在多线程的世界中,确保数据的一致性和线程间的有效通信是至关重要的。本文将深入探讨Java并发编程中的核心概念——线程同步与锁机制。我们将从基本的synchronized关键字开始,逐步过渡到更复杂的ReentrantLock类,并探讨它们如何帮助我们在多线程环境中保持数据完整性和避免常见的并发问题。文章还将通过示例代码,展示这些同步工具在实际开发中的应用,帮助读者构建对Java并发编程深层次的理解。
|
3天前
|
安全 Java 测试技术
Java并发编程:理解线程同步和锁
【5月更文挑战第25天】本文深入探讨了Java并发编程的核心概念,即线程同步和锁。通过详细解释这两种机制,我们能够理解它们如何帮助解决多线程环境中的竞态条件问题。此外,文章还提供了一些示例代码,以展示如何在Java中使用这些技术。
|
6天前
|
Java 开发者
Java并发编程:理解线程同步和锁
【5月更文挑战第22天】本文将深入探讨Java并发编程的核心概念——线程同步和锁。我们将从基本的同步问题开始,逐步深入到更复杂的并发控制技术,包括可重入锁、读写锁以及Java并发工具库中的其他锁机制。通过理论与实例相结合的方式,读者将能够理解在多线程环境下如何保证数据的一致性和程序的正确性。
|
13天前
|
Linux API C++
c++多线程——互斥锁
c++多线程——互斥锁
|
22小时前
|
安全 算法 Java
Java多线程基础-15:Java 中 synchronized 的优化操作 -- 锁升级、锁消除、锁粗化
`synchronized`在Java并发编程中具有以下特性:开始时是乐观锁,竞争激烈时转为悲观锁;从轻量级锁升级至重量级锁;常使用自旋锁策略;是不公平且可重入的;不支持读写锁。
10 0
|
5天前
|
存储 安全 Java
Java锁策略-Java多线程(4)
Java锁策略-Java多线程(4)
5 0
|
13天前
|
Linux API
Linux系统编程之文件编程常用API回顾和文件编程一般步骤
Linux系统编程之文件编程常用API回顾和文件编程一般步骤
Linux系统编程之文件编程常用API回顾和文件编程一般步骤
|
13天前
|
安全 Java
【JAVA进阶篇教学】第十篇:Java中线程安全、锁讲解
【JAVA进阶篇教学】第十篇:Java中线程安全、锁讲解
|
13天前
|
安全 Java 程序员
【Java多线程】面试常考——锁策略、synchronized的锁升级优化过程以及CAS(Compare and swap)
【Java多线程】面试常考——锁策略、synchronized的锁升级优化过程以及CAS(Compare and swap)
16 0
|
13天前
|
Java
【Java多线程】分析线程加锁导致的死锁问题以及解决方案
【Java多线程】分析线程加锁导致的死锁问题以及解决方案
28 1