前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【线程同步】读写锁

【线程同步】读写锁

作者头像
mindtechnist
发布2024-08-08 17:19:32
790
发布2024-08-08 17:19:32
举报
文章被收录于专栏:机器和智能

1. 什么是读写锁

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

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

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

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

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

2. 读写锁相关API

2.1 读写锁的初始化与释放

  • 头文件及函数原型
代码语言:javascript
复制
#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 加读锁

  • 头文件及函数原型
代码语言:javascript
复制
#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 加写锁

  • 头文件及函数原型
代码语言:javascript
复制
#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 释放锁

  • 头文件及函数原型
代码语言:javascript
复制
#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. 案例分析

代码语言:javascript
复制
#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;
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-05-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 机器和智能 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 什么是读写锁
  • 2. 读写锁相关API
    • 2.1 读写锁的初始化与释放
      • 2.2 加读锁
        • 2.3 加写锁
          • 2.4 释放锁
          • 3. 案例分析
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档