【Linux线程同步专题】二、读写锁

简介: 【Linux线程同步专题】二、读写锁

1. 什么是读写锁

读写锁是一种与互斥量类似的锁,它允许更高的并行性,具有写独占,读共享的特点。读写锁总共有三种状态:

  • 读模式下加锁状态(读锁)
  • 写模式下加锁状态(写锁)
  • 不加锁状态

读写锁,所谓读共享写独占是指,加读锁的时候,可以多线程一块读,但是不能写;加写锁的时候,不能读,只有当前线程可以写。并且写优先级高于读。读写锁是一把锁,有上面三种状态。

  • 读写锁是写模式加锁的时候,解锁前,所有对该锁加锁的线程都会被阻塞;
  • 读写锁是读模式加锁的时候,如果线程以读模式对其加锁会成功;如果线程以写模式加锁会阻塞;
  • 读写锁是读模式加锁时,既有试图以写模式加锁的线程,又有以读模式加锁的线程,那么读写锁会阻塞随后的读模式加锁请求,优先满足写模式加锁。读锁写锁并行阻塞,写锁优先级高,也就是说线程1持有写锁,线程2请求写锁的同时线程3请求读锁(如果没有写锁申请,那么读锁加锁成功),这时候线程2和3都阻塞,线程1释放锁后,优先满足线程2写锁。

读写锁也叫做共享-独占锁,当读写锁以读模式锁住时,它是以共享模式锁住的;当它以写模式锁住时,它是以独占模式锁住的,也就是所谓的写独占,读共享。读写锁适用于对数据结构读的次数远大于写的情况,因为多线程加读锁的时候可以同时读,效率更高。

2. 读写锁相关API

2.1 读写锁的初始化与释放

  • 头文件及函数原型
#include <pthread.h>
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);
  • 函数描述
  • The pthread_rwlock_destroy() function shall destroy the read-write lock object referenced by rwlock and release any resources used by the lock.
  • The pthread_rwlock_init() function shall allocate any resources required to use the read-write lock referenced by rwlock and initializes the lock to an unlocked state with attributes referenced by attr.
  • 函数参数
  • 函数返回值
    If successful, the pthread_rwlock_destroy() and pthread_rwlock_init() functions shall return zero; otherwise, an error number shall be returned to indicate the error.

2.2 加读锁

  • 头文件及函数原型
#include <pthread.h>
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
  • 函数描述
  • The pthread_rwlock_rdlock() function shall apply a read lock to the read-write lock referenced by rwlock.
  • The pthread_rwlock_tryrdlock() function shall apply a read lock as in the pthread_rwlock_rdlock() function, with the exception that the function shall fail if the equivalent pthread_rwlock_rdlock() call would have blocked the calling thread.
  • 函数参数
  • 函数返回值
  • If successful, the pthread_rwlock_rdlock() function shall return zero; otherwise, an error number shall be returned to indicate the error.
  • The pthread_rwlock_tryrdlock() function shall return zero if the lock for reading on the read-write lock object referenced by rwlock is acquired. Otherwise, an error number shall be returned to indicate the error.

2.3 加写锁

  • 头文件及函数原型
#include <pthread.h>
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
  • 函数描述
    The pthread_rwlock_trywrlock() function shall apply a write lock like the pthread_rwlock_wrlock() function, with the exception that the function shall fail if any thread currently holds rwlock (for reading or writing).
  • 函数参数
  • 函数返回值
  • The pthread_rwlock_trywrlock() function shall return zero if the lock for writing on the read-write lock object referenced by rwlock is acquired. Otherwise, an error number shall be returned to indicate the error.
  • If successful, the pthread_rwlock_wrlock() function shall return zero; otherwise, an error number shall be returned to indicate the error.

2.4 释放锁

  • 头文件及函数原型
#include <pthread.h>
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
  • 函数描述
    The pthread_rwlock_unlock() function shall release a lock held on the read-write lock object referenced by rwlock.
  • 函数参数
  • 函数返回值
    If successful, the pthread_rwlock_unlock() function shall return zero; otherwise, an error number shall be returned to indicate the error.

3. 案例分析

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
int gdata = 100;
void* read_th(void* arg)
{
    while(1)
    {
        pthread_rwlock_rdlock(&rwlock);
        printf("read thread: %s, tid: %d, gdata: %d\n", __FUNCTION__, pthread_self(), gdata);
        usleep(8000);
        pthread_rwlock_unlock(&rwlock);
        usleep(6000);
    }
}
void* write_th(void* arg)
{
    while(1)
    {
        pthread_rwlock_wrlock(&rwlock);
        printf("write thread: %s, tid: %d, gdata: %d\n", __FUNCTION__, pthread_self(), ++gdata);
        usleep(8000);
        pthread_rwlock_unlock(&rwlock);
        usleep(9000);
    }
}
int main(int argc, char* argv[])
{
    pthread_t tid[6];
    for(i = 0; i < 4; i++)
    {
        pthread_create(&tid[i], NULL, read_th, NULL);
    }
    for(; i< 6; i++)
    {
        pthread_join(&tid[i], NULL, write_th, NULL);
    }
    for(i = 0; i < 6; i++)
    {
        pthread_join(tid[i], NULL);
    }
    return 0;
}


相关文章
|
11天前
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
本文详细介绍了如何在Linux中通过在业务线程中注册和处理信号。我们讨论了信号的基本概念,并通过完整的代码示例展示了在业务线程中注册和处理信号的方法。通过正确地使用信号处理机制,可以提高程序的健壮性和响应能力。希望本文能帮助您更好地理解和应用Linux信号处理,提高开发效率和代码质量。
40 17
|
20天前
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
通过本文,您可以了解如何在业务线程中注册和处理Linux信号。正确处理信号可以提高程序的健壮性和稳定性。希望这些内容能帮助您更好地理解和应用Linux信号处理机制。
52 26
|
2月前
|
监控 算法 Linux
Linux内核锁机制深度剖析与实践优化####
本文作为一篇技术性文章,深入探讨了Linux操作系统内核中锁机制的工作原理、类型及其在并发控制中的应用,旨在为开发者提供关于如何有效利用这些工具来提升系统性能和稳定性的见解。不同于常规摘要的概述性质,本文将直接通过具体案例分析,展示在不同场景下选择合适的锁策略对于解决竞争条件、死锁问题的重要性,以及如何根据实际需求调整锁的粒度以达到最佳效果,为读者呈现一份实用性强的实践指南。 ####
|
3月前
|
算法 Linux 开发者
Linux内核中的锁机制:保障并发控制的艺术####
本文深入探讨了Linux操作系统内核中实现的多种锁机制,包括自旋锁、互斥锁、读写锁等,旨在揭示这些同步原语如何高效地解决资源竞争问题,保证系统的稳定性和性能。通过分析不同锁机制的工作原理及应用场景,本文为开发者提供了在高并发环境下进行有效并发控制的实用指南。 ####
|
3月前
|
Linux 数据库
Linux内核中的锁机制:保障并发操作的数据一致性####
【10月更文挑战第29天】 在多线程编程中,确保数据一致性和防止竞争条件是至关重要的。本文将深入探讨Linux操作系统中实现的几种关键锁机制,包括自旋锁、互斥锁和读写锁等。通过分析这些锁的设计原理和使用场景,帮助读者理解如何在实际应用中选择合适的锁机制以优化系统性能和稳定性。 ####
88 6
|
4月前
|
资源调度 Linux 调度
Linux C/C++之线程基础
这篇文章详细介绍了Linux下C/C++线程的基本概念、创建和管理线程的方法,以及线程同步的各种机制,并通过实例代码展示了线程同步技术的应用。
63 0
Linux C/C++之线程基础
|
4月前
|
安全 Linux
Linux线程(十一)线程互斥锁-条件变量详解
Linux线程(十一)线程互斥锁-条件变量详解
|
2月前
|
存储 安全 Java
Java多线程编程秘籍:各种方案一网打尽,不要错过!
Java 中实现多线程的方式主要有四种:继承 Thread 类、实现 Runnable 接口、实现 Callable 接口和使用线程池。每种方式各有优缺点,适用于不同的场景。继承 Thread 类最简单,实现 Runnable 接口更灵活,Callable 接口支持返回结果,线程池则便于管理和复用线程。实际应用中可根据需求选择合适的方式。此外,还介绍了多线程相关的常见面试问题及答案,涵盖线程概念、线程安全、线程池等知识点。
236 2
|
3月前
|
设计模式 Java 开发者
Java多线程编程的陷阱与解决方案####
本文深入探讨了Java多线程编程中常见的问题及其解决策略。通过分析竞态条件、死锁、活锁等典型场景,并结合代码示例和实用技巧,帮助开发者有效避免这些陷阱,提升并发程序的稳定性和性能。 ####
|
3月前
|
缓存 Java 开发者
Java多线程编程的陷阱与最佳实践####
本文深入探讨了Java多线程编程中常见的陷阱,如竞态条件、死锁和内存一致性错误,并提供了实用的避免策略。通过分析典型错误案例,本文旨在帮助开发者更好地理解和掌握多线程环境下的编程技巧,从而提升并发程序的稳定性和性能。 ####