线程同步之读写锁

文章目录

读写锁

  • 读/写锁(Read-Write Lock)是另外一种避免多个线程同时修改临界资源的一种互斥机制
  • 是一种更灵活的同步机制,适用于读多写少的场景
  • 允许多个线程同时读取共享资源,但写入时必须独占访问

特点

  • 读锁(共享锁):允许多个线程同时获取
  • 写锁(独占锁):只允许一个线程获取,且获取时不能有任何读锁或写锁
  • 优先级策略:通常写锁优先(防止写线程饿死)

读写锁 vs 互斥锁

特性 互斥锁 (Mutex) 读写锁 (RWLock)
读操作 串行(一次一个线程) 并行(多个线程可同时读)
写操作 串行 串行(独占)
适用场景 读写频率相当 读多写少
性能 一般 高并发读时性能更优

函数接口

初始化

c 复制代码
// 静态初始化(全局/静态变量)
pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;

// 动态初始化(栈/堆变量)
int pthread_rwlock_init(pthread_rwlock_t *rwlock, 
                       const pthread_rwlockattr_t *attr);

加锁操作

c 复制代码
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);  // 获取读锁
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);  // 获取写锁
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock); // 尝试读锁
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock); // 尝试写锁

解锁操作

c 复制代码
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);  // 解锁(读/写锁通用)

销毁

c 复制代码
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);

读写锁解决同步问题

c 复制代码
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

#define NUM_READERS 3
#define NUM_WRITERS 2

int balance = 1000;
pthread_rwlock_t rwlock;

void* reader(void* id_ptr) {
    int id = *(int*)id_ptr;
    while(1) {
        pthread_rwlock_rdlock(&rwlock);
        printf("读者%d: 查询余额 = %d\n", id, balance);
        pthread_rwlock_unlock(&rwlock);
        sleep(1);
    }
    return NULL;
}

void* writer(void* id_ptr) {
    int id = *(int*)id_ptr;
    while(1) {
        int amount = 100;
        pthread_rwlock_wrlock(&rwlock);
        balance += amount;
        printf("写者%d: 存入%d, 新余额 = %d\n", id, amount, balance);
        pthread_rwlock_unlock(&rwlock);
        sleep(2);  // 写操作间隔较长
    }
    return NULL;
}

int main() {
    pthread_t readers[NUM_READERS], writers[NUM_WRITERS];
    int r_ids[NUM_READERS], w_ids[NUM_WRITERS];
    
    pthread_rwlock_init(&rwlock, NULL);
    
    // 创建读者
    for(int i = 0; i < NUM_READERS; i++) {
        r_ids[i] = i + 1;
        pthread_create(&readers[i], NULL, reader, &r_ids[i]);
    }
    
    // 创建写者
    for(int i = 0; i < NUM_WRITERS; i++) {
        w_ids[i] = i + 1;
        pthread_create(&writers[i], NULL, writer, &w_ids[i]);
    }
    
    // 等待(实际上无限循环)
    for(int i = 0; i < NUM_READERS; i++) {
        pthread_join(readers[i], NULL);
    }
    
    pthread_rwlock_destroy(&rwlock);
    return 0;
}
latex 复制代码
时间线:
线程1: R[lock] --- 读操作 --- R[unlock]
线程2:           R[lock] --- 读操作 --- R[unlock]  ← 可同时读
线程3:                             W[lock] --- 写操作 --- W[unlock] ← 独占

注意事项

避免死锁

c 复制代码
// 错误:同一线程内重复加写锁
pthread_rwlock_wrlock(&rwlock);
pthread_rwlock_wrlock(&rwlock);  // 死锁

// 正确:解锁后再加锁
pthread_rwlock_wrlock(&rwlock);
// ... 操作
pthread_rwlock_unlock(&rwlock);
pthread_rwlock_wrlock(&rwlock);  // 重新获取
相关推荐
烛衔溟1 天前
C语言并发编程:Windows线程
c语言·c++·windows·性能优化·多线程·并发编程·线程同步
我在人间贩卖青春2 天前
线程同步之条件变量
条件变量·线程同步·生产者与消费者·虚假唤醒
我在人间贩卖青春3 天前
线程同步之互斥量
互斥锁·线程同步·互斥量
工程师00722 天前
线程同步的意义
c#·锁机制·线程同步
喵手1 个月前
线程同步:确保多线程环境中的数据一致性!
java·线程同步
egoist20232 个月前
[linux仓库]线程同步与生产者消费者模型[线程·陆]
linux·c语言·开发语言·线程同步·阻塞队列·生产者消费者模型
阿巴~阿巴~2 个月前
Linux同步机制:POSIX 信号量 与 SystemV信号量 的 对比
linux·服务器·线程·信号量·线程同步·posix·system v
hour_go3 个月前
C++多线程编程入门实战
c++·并发编程·互斥锁·线程同步·原子操作
维度攻城狮3 个月前
C++中的多线程编程及线程同步
开发语言·c++·性能优化·多线程·线程同步