【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);


目录
相关文章
|
3月前
|
安全 Java API
告别繁琐编码,拥抱Java 8新特性:Stream API与Optional类助你高效编程,成就卓越开发者!
【8月更文挑战第29天】Java 8为开发者引入了多项新特性,其中Stream API和Optional类尤其值得关注。Stream API对集合操作进行了高级抽象,支持声明式的数据处理,避免了显式循环代码的编写;而Optional类则作为非空值的容器,有效减少了空指针异常的风险。通过几个实战示例,我们展示了如何利用Stream API进行过滤与转换操作,以及如何借助Optional类安全地处理可能为null的数据,从而使代码更加简洁和健壮。
107 0
|
7天前
|
Linux 数据库
Linux内核中的锁机制:保障并发操作的数据一致性####
【10月更文挑战第29天】 在多线程编程中,确保数据一致性和防止竞争条件是至关重要的。本文将深入探讨Linux操作系统中实现的几种关键锁机制,包括自旋锁、互斥锁和读写锁等。通过分析这些锁的设计原理和使用场景,帮助读者理解如何在实际应用中选择合适的锁机制以优化系统性能和稳定性。 ####
24 6
|
14天前
|
缓存 安全 C++
C++无锁队列:解锁多线程编程新境界
【10月更文挑战第27天】
29 7
|
14天前
|
消息中间件 存储 安全
|
1月前
|
存储 消息中间件 资源调度
C++ 多线程之初识多线程
这篇文章介绍了C++多线程的基本概念,包括进程和线程的定义、并发的实现方式,以及如何在C++中创建和管理线程,包括使用`std::thread`库、线程的join和detach方法,并通过示例代码展示了如何创建和使用多线程。
41 1
C++ 多线程之初识多线程
|
21天前
|
存储 并行计算 安全
C++多线程应用
【10月更文挑战第29天】C++ 中的多线程应用广泛,常见场景包括并行计算、网络编程中的并发服务器和图形用户界面(GUI)应用。通过多线程可以显著提升计算速度和响应能力。示例代码展示了如何使用 `pthread` 库创建和管理线程。注意事项包括数据同步与互斥、线程间通信和线程安全的类设计,以确保程序的正确性和稳定性。
|
1月前
|
存储 前端开发 C++
C++ 多线程之带返回值的线程处理函数
这篇文章介绍了在C++中使用`async`函数、`packaged_task`和`promise`三种方法来创建带返回值的线程处理函数。
45 6
|
1月前
|
缓存 负载均衡 Java
c++写高性能的任务流线程池(万字详解!)
本文介绍了一种高性能的任务流线程池设计,涵盖多种优化机制。首先介绍了Work Steal机制,通过任务偷窃提高资源利用率。接着讨论了优先级任务,使不同优先级的任务得到合理调度。然后提出了缓存机制,通过环形缓存队列提升程序负载能力。Local Thread机制则通过预先创建线程减少创建和销毁线程的开销。Lock Free机制进一步减少了锁的竞争。容量动态调整机制根据任务负载动态调整线程数量。批量处理机制提高了任务处理效率。此外,还介绍了负载均衡、避免等待、预测优化、减少复制等策略。最后,任务组的设计便于管理和复用多任务。整体设计旨在提升线程池的性能和稳定性。
74 5
|
1月前
|
C++
C++ 多线程之线程管理函数
这篇文章介绍了C++中多线程编程的几个关键函数,包括获取线程ID的`get_id()`,延时函数`sleep_for()`,线程让步函数`yield()`,以及阻塞线程直到指定时间的`sleep_until()`。
23 0
C++ 多线程之线程管理函数
|
1月前
|
资源调度 Linux 调度
Linux C/C++之线程基础
这篇文章详细介绍了Linux下C/C++线程的基本概念、创建和管理线程的方法,以及线程同步的各种机制,并通过实例代码展示了线程同步技术的应用。
28 0
Linux C/C++之线程基础