线程同步——读写锁

无论是自旋锁还是互斥锁,他们通过加锁和解锁保证临界资源不会被并发访问的原则是当一个线程正在访问临界资源,会阻止其他线程访问临界资源。

读写锁

读写锁一定程度上对上述两种锁进行改进。
最重要的特点是根据临界资源很可能存在多读少写这一特性,比如某一商城的历史订单数据库,对于历史订单都是查询较多,很少进行更改。对于多读少些的临界资源在读取的时候并不会改变它的值。如果每一次读或写临界资源都进行加锁,效率会非常低。

  • 读写锁其实是一种特殊的自旋锁
  • 允许多个读者同时访问资源以提高读的性能
  • 对于写操作是互斥的,即不允许多个写操作同时访问

模型

读写锁使用pthread_rwlock_t
加锁有两种方法,分别加读锁和写锁。
读锁 pthread_rwlock_rdlock
读锁 pthread_rwlock_wrlock

//
// Created by 文若 on 2020/9/5.
//

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <vector>

// 临界资源
int num = 0;

pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;

void *reader(void *) {
    int times = 1000000;
    while (times--) {
        // 读前加读锁
        pthread_rwlock_rdlock(&rwlock);
        if (times % 1000 == 0) {
            usleep(10); // 睡眠10微妙查看性能
        }
        pthread_rwlock_unlock(&rwlock);
    }
}

void *writer(void *) {
    int times = 1000000;
    while (times--) {
        // 写前写锁
        pthread_rwlock_wrlock(&rwlock);
        num += 1;
        pthread_rwlock_unlock(&rwlock);
    }
}

int main() {

    pthread_t thread1, thread2, thread3;
    pthread_create(&thread1, NULL, &reader, NULL);
    pthread_create(&thread2, NULL, &reader, NULL);
    pthread_create(&thread3, NULL, &writer, NULL);
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
    pthread_join(thread3, NULL);
    printf("临界资源:%d\n", num);
    
    return 0;
}

猜你喜欢

转载自blog.csdn.net/wankcn/article/details/108414581