讀寫鎖


(1) 讀寫鎖是幾把鎖
  一把鎖
  pthread_rwlock_t lock;

(2) 讀寫鎖的類型
  讀鎖: 對內存做讀操作
  寫鎖: 對內存做寫操作

(3) 讀寫鎖的特性:
  線程A加讀鎖成功, 又來了三個線程, 做讀操作, 可以加鎖成功
    讀共享, 並行處理
  線程A加寫鎖成功, 又來了三個線程, 做讀操作, 三個線程阻塞
    寫讀占, 串行處理
  線程A加讀鎖成功, 又來了B線程加寫鎖阻塞, 在B之后來了C線程加讀鎖阻塞
    讀寫不能同時進行
    寫的優先級高

(4) 讀寫鎖場景練習
線程A加寫鎖成功, 線程B請求讀鎖:
  線程B阻塞
線程A持有讀鎖, 線程B請求寫鎖:
  線程B阻塞
線程A擁有讀鎖, 線程B請求讀鎖
  線程B加鎖成功
線程A持有讀鎖, 然后線程B請求寫鎖, 然后線程B請求讀鎖
  B阻塞, C阻塞 --> 寫的優先級高
  A解鎖, B線程加寫鎖成功, C繼續阻塞
  B解鎖, C加讀鎖成功
線程A持有寫鎖, 然后線程B請求讀鎖, 然后線程C請求寫鎖
  B, C阻塞
  A解鎖, C加寫鎖, B阻塞
  C解鎖, B加鎖成功

(5) 讀寫鎖使用場景
互斥鎖--> 讀寫串行
讀寫鎖--> 讀: 並行; 寫: 串行
程序中讀操作大於寫操作

(6) 主要處理函數
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr); 初始化讀寫鎖

int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);銷毀讀寫鎖

int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);加讀鎖
  阻塞: 之前對這把鎖加的寫鎖的操作
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);嘗試加讀鎖
  加鎖成功: 0; 加鎖失敗: 錯誤號
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);加寫鎖
  阻塞: 上一次加寫鎖還沒有解鎖; 上一次加讀鎖沒解鎖
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);嘗試加寫鎖

int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);解鎖

(7) 讀寫鎖和互斥鎖, 並不是任何時候都能阻塞線程

(8) 練習
3個線程不定時寫同一全局資源, 5個線程不定時讀同一全局資源

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <pthread.h>

int number = 0;

// 讀寫鎖
pthread_rwlock_t lock;

void *write_func(void *arg) {
    while (1) {
        pthread_rwlock_wrlock(&lock);
        number++;
        printf("+++++write: %lu, %d\n", pthread_self(),  number);
        pthread_rwlock_unlock(&lock);
        sleep(1);
    }
    return NULL;
}

void *read_func(void *arg) {
    while (1) {
        pthread_rwlock_rdlock(&lock);
        printf("======read: %lu, %d\n", pthread_self(), number);
        pthread_rwlock_unlock(&lock);
        sleep(1);
    }
    return NULL;
}

int main() {
    int i;
    pthread_t p[8];

    // 初始化讀寫鎖
    pthread_rwlock_init(&lock, NULL);

    // 3個寫線程
    for (i = 0; i < 3; i++) {
        pthread_create(&p[i], NULL, write_func, NULL);
    }
    
    // 5個讀線程
    for (i = 3; i < 8; i++) {
        pthread_create(&p[i], NULL, read_func, NULL);
    }

    // 回收子線程
    for (i = 0; i < 8; i++) {
        pthread_join(p[i], NULL);
    }

    for (i = 0; i < 8; i++) {
        pthread_rwlock_destroy(&lock);
    }

    return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM