自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Linux多線程同步機(jī)制—讀寫鎖(Read-Write Lock)

系統(tǒng) Linux
讀寫鎖相比于傳統(tǒng)的互斥鎖(mutex)具有更高的并發(fā)性能,特別是在讀操作遠(yuǎn)多于寫操作的場(chǎng)景下。這是因?yàn)樽x寫鎖允許多個(gè)讀線程同時(shí)訪問(wèn)共享資源,從而減少了線程間的等待時(shí)間,提高了系統(tǒng)的整體吞吐量。

概述

讀寫鎖(Read-Write Lock)是一種線程同步機(jī)制,用于管理對(duì)共享資源的訪問(wèn)。與互斥鎖(Mutex)不同,讀寫鎖允許多個(gè)線程同時(shí)以讀模式訪問(wèn)共享資源,但只允許一個(gè)線程以寫模式訪問(wèn)資源。這種機(jī)制特別適用于讀操作遠(yuǎn)多于寫操作的場(chǎng)景,可以顯著提高程序的并發(fā)性能。

讀寫鎖原理

讀寫鎖的設(shè)計(jì)基于以下原則:

  • 讀操作共享:允許多個(gè)讀線程同時(shí)訪問(wèn)共享資源,只要沒(méi)有寫線程正在訪問(wèn)或等待訪問(wèn)資源。
  • 寫操作排他:在任何時(shí)候,只允許一個(gè)寫線程訪問(wèn)共享資源。在寫線程持有鎖期間,所有的讀線程和寫線程都將被阻塞。

讀寫鎖內(nèi)部實(shí)現(xiàn)機(jī)制

讀寫鎖的內(nèi)部實(shí)現(xiàn)通常依賴于一個(gè)或多個(gè)底層鎖和一些額外的狀態(tài)信息。以下是一種常見的實(shí)現(xiàn)方式:

  • 計(jì)數(shù)器:用于跟蹤當(dāng)前有多少讀線程正在持有讀鎖。通常,當(dāng)計(jì)數(shù)器大于 0 時(shí),表示有讀線程正在訪問(wèn)資源,此時(shí)不允許寫線程獲取鎖;當(dāng)計(jì)數(shù)器為 0 時(shí),表示沒(méi)有讀線程持有鎖,寫線程可以嘗試獲取鎖。
  • 寫鎖標(biāo)志:用于標(biāo)記是否有寫線程正在持有鎖或者有寫線程正在等待獲取鎖。當(dāng)寫鎖標(biāo)志為真時(shí),所有讀線程和寫線程都將被阻塞,直到寫線程釋放鎖。
  • 底層互斥鎖和條件變量:讀寫鎖通常會(huì)使用一個(gè)互斥鎖來(lái)保護(hù)其內(nèi)部狀態(tài)(如計(jì)數(shù)器和寫鎖標(biāo)志),以及一個(gè)或多個(gè)條件變量來(lái)實(shí)現(xiàn)線程間的等待和喚醒機(jī)制。

讀寫鎖的典型實(shí)現(xiàn)

在 Linux 和 POSIX 兼容的系統(tǒng)中,讀寫鎖通常通過(guò) pthread_rwlock_t 類型實(shí)現(xiàn)。其內(nèi)部可能包含如下組件:

  • 互斥鎖(Mutex):用于保護(hù)讀寫鎖的內(nèi)部狀態(tài),如讀計(jì)數(shù)器和寫鎖狀態(tài)。
  • 讀計(jì)數(shù)器(Read Counter):記錄當(dāng)前持有讀鎖的線程數(shù)量。
  • 條件變量(Condition Variable):用于實(shí)現(xiàn)線程的等待和通知機(jī)制。通常,會(huì)有兩個(gè)條件變量,一個(gè)用于讀線程,一個(gè)用于寫線程。

當(dāng)線程嘗試獲取讀鎖時(shí),它會(huì)檢查寫鎖狀態(tài)和讀計(jì)數(shù)器,如果當(dāng)前沒(méi)有寫線程正在訪問(wèn)資源,則增加讀計(jì)數(shù)器并允許讀線程繼續(xù);如果存在寫操作,則讀線程將被阻塞,直到寫操作完成。

類似地,當(dāng)線程嘗試獲取寫鎖時(shí),它會(huì)檢查讀計(jì)數(shù)器和寫鎖狀態(tài)。如果當(dāng)前沒(méi)有讀線程和寫線程正在訪問(wèn)資源,則設(shè)置寫鎖狀態(tài)并允許寫線程繼續(xù);如果有讀線程或?qū)懢€程正在訪問(wèn)資源,則寫線程將被阻塞,直到所有讀線程和前一個(gè)寫線程完成操作。

讀寫鎖相關(guān)API

當(dāng)然,我會(huì)補(bǔ)充完整上面的程序,并進(jìn)一步完善API函數(shù)的描述。請(qǐng)注意,由于程序中的線程是無(wú)限循環(huán)的,為了示例的完整性,我將添加一個(gè)全局變量作為退出條件。此外,我將更詳細(xì)地解釋API函數(shù)的使用。

pthread_rwlock_init -- 初始化讀寫鎖

int pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr);
  • 參數(shù):

rwlock:指向要初始化的讀寫鎖變量的指針。

attr:(可選)指向讀寫鎖屬性的指針。如果傳遞NULL,則使用默認(rèn)屬性。

  • 返回值:成功時(shí)返回0,失敗時(shí)返回錯(cuò)誤碼。

pthread_rwlock_destroy -- 銷毀讀寫鎖

int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
  • 參數(shù):

rwlock:指向要銷毀的讀寫鎖變量的指針。

  • 返回值:成功時(shí)返回0,失敗時(shí)返回錯(cuò)誤碼。

pthread_rwlock_rdlock -- 加讀鎖

int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
  • 參數(shù):

rwlock:指向讀寫鎖變量的指針。

  • 返回值:成功時(shí)返回0,失敗時(shí)返回錯(cuò)誤碼。如果鎖被其他線程以寫模式持有,則調(diào)用線程將被阻塞。

pthread_rwlock_wrlock -- 加寫鎖

int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
  • 參數(shù):

rwlock:指向讀寫鎖變量的指針。

  • 返回值:成功時(shí)返回0,失敗時(shí)返回錯(cuò)誤碼。如果鎖被其他線程以讀模式或?qū)懩J匠钟校瑒t調(diào)用線程將被阻塞。

pthread_rwlock_tryrdlock -- 嘗試加讀鎖(非阻塞)

int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
  • 參數(shù):

rwlock:指向讀寫鎖變量的指針。

  • 返回值:成功時(shí)返回0,如果鎖不可用,則返回EBUSY。

C 語(yǔ)言實(shí)現(xiàn)讀寫鎖

一、封裝POSIX 線程庫(kù)的讀寫鎖

封裝 POSIX 線程庫(kù)提供的pthread_rwlock_t類型的讀寫鎖,以及相關(guān)的操作函數(shù)pthread_rwlock_rdlock、pthread_rwlock_wrlock等,即可實(shí)現(xiàn)簡(jiǎn)單的讀寫鎖,無(wú)需自行實(shí)現(xiàn)復(fù)雜的邏輯。以下是一個(gè)簡(jiǎn)單的 C 語(yǔ)言實(shí)現(xiàn)讀寫鎖的代碼:

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

// 定義讀寫鎖結(jié)構(gòu)體
typedef struct {
    pthread_rwlock_t rwlock; // 使用 POSIX 的讀寫鎖
} rwlock_t;

// 定義線程參數(shù)結(jié)構(gòu)體
typedef struct thread_params {
    rwlock_t *lock;
    int id; // 線程標(biāo)識(shí)符
} thread_params_t;

// 初始化讀寫鎖
void rwlock_init(rwlock_t *lock) {
    pthread_rwlock_init(&lock->rwlock, NULL);
}

// 銷毀讀寫鎖并釋放資源
void rwlock_destroy(rwlock_t *lock) {
    pthread_rwlock_destroy(&lock->rwlock);
}

// 獲取讀鎖
void rwlock_read_lock(rwlock_t *lock) {
    pthread_rwlock_rdlock(&lock->rwlock);
}

// 釋放讀鎖
void rwlock_read_unlock(rwlock_t *lock) {
    pthread_rwlock_unlock(&lock->rwlock);
}

// 獲取寫鎖
void rwlock_write_lock(rwlock_t *lock) {
    pthread_rwlock_wrlock(&lock->rwlock);
}

// 釋放寫鎖
void rwlock_write_unlock(rwlock_t *lock) {
    pthread_rwlock_unlock(&lock->rwlock);
}

// 讀者線程函數(shù)
void *reader(void *arg) {
    thread_params_t *params = arg; // 從參數(shù)中獲取線程參數(shù)結(jié)構(gòu)體
    int i;
    for (i = 0; i < 3; i++) {
        rwlock_read_lock(params->lock);
        printf("讀者線程 %d: 正在讀取...\n", params->id);
        usleep(100000);
        rwlock_read_unlock(params->lock);
    }
    return NULL;
}

// 寫者線程函數(shù)
void *writer(void *arg) {
    thread_params_t *params = arg; // 從參數(shù)中獲取線程參數(shù)結(jié)構(gòu)體
    int i;
    for (i = 0; i < 5; i++) {
        rwlock_write_lock(params->lock);
        printf("寫者線程 %d: 正在寫入...\n", params->id);
        usleep(500000);
        rwlock_write_unlock(params->lock);
    }
    return NULL;
}

int main() {
    rwlock_t lock;
    rwlock_init(&lock);

    pthread_t threads[5];
    thread_params_t thread_params[5]; // 定義線程參數(shù)數(shù)組

    int i;

    // 初始化線程參數(shù)數(shù)組
    for (i = 0; i < 5; i++) {
        thread_params[i].lock = &lock;
        thread_params[i].id = i + 1; // 分配線程標(biāo)識(shí)符
    }

    // 創(chuàng)建讀者線程
    for (i = 0; i < 4; i++) {
        pthread_create(&threads[i], NULL, reader, &thread_params[i]);
    }

    // 創(chuàng)建寫者線程
    pthread_create(&threads[4], NULL, writer, &thread_params[4]);

    // 加入所有線程,等待它們完成
    for (i = 0; i < 5; i++) {
        pthread_join(threads[i], NULL);
    }

    rwlock_destroy(&lock);

    return 0;
}

注意:封裝 rwlock_t 結(jié)構(gòu)體的主要原因在于提供一個(gè)清晰、模塊化的接口來(lái)管理和使用讀寫鎖,這帶來(lái)了以下幾方面的優(yōu)勢(shì):

  1. 封裝細(xì)節(jié):

將讀寫鎖的實(shí)現(xiàn)細(xì)節(jié)封裝在rwlock_t結(jié)構(gòu)體內(nèi),對(duì)外只暴露必要的接口(如初始化、銷毀、讀鎖和寫鎖操作)。這樣做的好處是隱藏了內(nèi)部實(shí)現(xiàn)的復(fù)雜性,外部調(diào)用者只需要關(guān)注如何使用鎖,而不必關(guān)心鎖的具體實(shí)現(xiàn)。

  1. 類型安全:

使用專門的結(jié)構(gòu)體類型rwlock_t來(lái)表示讀寫鎖,增強(qiáng)了類型安全。這意味著在使用讀寫鎖的地方,編譯器可以檢查是否正確使用了讀寫鎖相關(guān)的函數(shù),避免了類型錯(cuò)誤。

  1. 可擴(kuò)展性:

如果將來(lái)需要改變讀寫鎖的實(shí)現(xiàn)方式,比如從使用pthread_rwlock_t切換到另一種鎖機(jī)制,只需修改rwlock_t結(jié)構(gòu)體和相關(guān)操作函數(shù),而無(wú)需修改所有使用讀寫鎖的地方。這大大提高了代碼的可維護(hù)性和可擴(kuò)展性。

  1. 代碼組織與重用:

封裝讀寫鎖的操作在一個(gè)獨(dú)立的結(jié)構(gòu)體和一組函數(shù)中,使得代碼更加整潔、有條理。此外,這樣的封裝有利于代碼的重用,如果項(xiàng)目中其他地方也需要使用讀寫鎖,可以直接引用rwlock_t及相關(guān)函數(shù),無(wú)需重復(fù)編寫相同的代碼。

  1. 測(cè)試與調(diào)試便利性:

將讀寫鎖的創(chuàng)建、使用和銷毀操作集中在一個(gè)結(jié)構(gòu)體及其相關(guān)函數(shù)中,方便了單元測(cè)試和調(diào)試??梢元?dú)立地測(cè)試讀寫鎖的功能,確保其在各種情況下的正確性。

綜上所述,封裝rwlock_t結(jié)構(gòu)體是軟件工程中一種常見的抽象和封裝機(jī)制,它不僅提高了代碼的可讀性和可維護(hù)性,也增強(qiáng)了系統(tǒng)的靈活性和健壯性。

這個(gè)示例中的關(guān)鍵點(diǎn)詳細(xì)闡述如下:

1. 讀寫鎖結(jié)構(gòu)體定義 (rwlock_t)

  • 定義:
typedef struct {
    pthread_rwlock_t rwlock; // 使用 POSIX 的讀寫鎖
} rwlock_t;
  • 解析:

rwlock_t結(jié)構(gòu)體封裝了一個(gè)pthread_rwlock_t類型的讀寫鎖實(shí)例。

pthread_rwlock_t 是 POSIX 標(biāo)準(zhǔn)中定義的一種高級(jí)鎖機(jī)制,允許同時(shí)存在多個(gè)讀操作,但寫操作是排他的,確保了數(shù)據(jù)在并發(fā)訪問(wèn)時(shí)的一致性。

2. 線程參數(shù)結(jié)構(gòu)體定義 (thread_params_t)

  • 定義:
typedef struct thread_params {
    rwlock_t *lock;
    int id; // 線程標(biāo)識(shí)符
} thread_params_t;
  • 解析:

thread_params_t 結(jié)構(gòu)體用于存儲(chǔ)線程運(yùn)行所需的信息,包括指向讀寫鎖的指針和線程的唯一標(biāo)識(shí)符。

這種設(shè)計(jì)允許線程函數(shù)以統(tǒng)一的方式接收參數(shù),增強(qiáng)代碼的可讀性和可維護(hù)性。

3. 讀寫鎖操作函數(shù)

  • 初始化與銷毀:
void rwlock_init(rwlock_t *lock);
void rwlock_destroy(rwlock_t *lock);

rwlock_init 負(fù)責(zé)初始化讀寫鎖,確保其處于可用狀態(tài)。

rwlock_destroy 用于清理鎖資源,避免內(nèi)存泄漏。

解析:

  • 讀鎖操作:
void rwlock_read_lock(rwlock_t *lock);
void rwlock_read_unlock(rwlock_t *lock);
  • rwlock_read_lock 獲取讀鎖,允許多個(gè)讀線程同時(shí)訪問(wèn)共享資源。

  • rwlock_read_unlock 釋放讀鎖,使其他線程有機(jī)會(huì)獲取鎖。

  • 解析:

  • 寫鎖操作:

    void rwlock_write_lock(rwlock_t *lock);
    void rwlock_write_unlock(rwlock_t *lock);

  • rwlock_write_lock 獲取寫鎖,確保寫操作的排他性,防止數(shù)據(jù)競(jìng)爭(zhēng)。

  • rwlock_write_unlock 釋放寫鎖,使其他線程可以繼續(xù)執(zhí)行。

  • 解析:

4. 線程函數(shù)

  • 讀者線程:
void *reader(void *arg);

讀者線程函數(shù) reader 接收一個(gè) thread_params_t 類型的參數(shù),從中提取讀寫鎖和線程標(biāo)識(shí)符。

線程執(zhí)行多次讀操作,每次讀取前獲取讀鎖,讀取后釋放讀鎖。

解析:

  • 寫者線程:
void *writer(void *arg);
  • 寫者線程函數(shù) writer 同樣接收 thread_params_t 類型的參數(shù)。

  • 線程執(zhí)行多次寫操作,每次寫入前獲取寫鎖,寫入后釋放寫鎖。

  • 解析:

5. 主函數(shù) (main)

  • 初始化與線程創(chuàng)建:

初始化讀寫鎖。

創(chuàng)建線程參數(shù)數(shù)組,為每個(gè)線程分配唯一標(biāo)識(shí)符和讀寫鎖引用。

使用pthread_create 創(chuàng)建 4 個(gè)讀者線程和 1 個(gè)寫者線程。

  • 線程同步與資源清理:
  • 使用 pthread_join 確保所有線程完成后再繼續(xù)執(zhí)行。

  • 調(diào)用 rwlock_destroy 銷毀讀寫鎖,釋放相關(guān)資源。

6. 線程標(biāo)識(shí)符

  • 功能:

每個(gè)線程擁有一個(gè)從 1 開始的唯一標(biāo)識(shí)符,便于在日志和調(diào)試信息中區(qū)分不同線程。

7. POSIX讀寫鎖機(jī)制

  • 優(yōu)勢(shì):

支持多個(gè)讀線程的同時(shí)訪問(wèn),提高了讀密集型應(yīng)用的并發(fā)性能。

確保寫操作的排他性,避免數(shù)據(jù)損壞,適用于寫操作較少的場(chǎng)景。

8. 線程創(chuàng)建與管理

  • 細(xì)節(jié):

使用pthread_create創(chuàng)建線程,傳入線程函數(shù)和參數(shù)。

利用pthread_join等待線程結(jié)束,保證程序的正確性和資源的有序釋放。

9. 資源管理

  • 重要性:

通過(guò)初始化和銷毀讀寫鎖,確保了鎖資源的生命周期管理,避免了內(nèi)存泄漏和資源浪費(fèi)。

編譯并執(zhí)行程序,結(jié)果如下:

[root@localhost rwlock]# gcc pthread_rwlock.c -o pthread_rwlock -lpthread
[root@localhost rwlock]# ls
pthread_rwlock  pthread_rwlock.c
[root@localhost rwlock]# ./pthread_rwlock
讀者線程 1: 正在讀取...
讀者線程 2: 正在讀取...
讀者線程 3: 正在讀取...
讀者線程 4: 正在讀取...
讀者線程 1: 正在讀取...
讀者線程 2: 正在讀取...
讀者線程 4: 正在讀取...
讀者線程 3: 正在讀取...
讀者線程 1: 正在讀取...
讀者線程 2: 正在讀取...
讀者線程 4: 正在讀取...
讀者線程 3: 正在讀取...
寫者線程 5: 正在寫入...
寫者線程 5: 正在寫入...
寫者線程 5: 正在寫入...
寫者線程 5: 正在寫入...
寫者線程 5: 正在寫入...

通過(guò)深入解析上述代碼和結(jié)果,我們可以更全面地理解基于 POSIX 讀寫鎖的多線程程序設(shè)計(jì)策略,以及如何有效利用鎖機(jī)制來(lái)提高并發(fā)應(yīng)用的性能和可靠性。

二、自定義實(shí)現(xiàn)的典型讀寫鎖

自定義實(shí)現(xiàn)讀寫鎖代碼需要開發(fā)者更深入地理解讀寫鎖的底層實(shí)現(xiàn)原理。完全自行實(shí)現(xiàn)讀寫鎖的邏輯,通過(guò)互斥鎖、條件變量以及自定義的讀計(jì)數(shù)和寫標(biāo)志來(lái)管理讀寫操作的同步。以下是一段 C 語(yǔ)言實(shí)現(xiàn)自定義實(shí)現(xiàn)讀寫鎖的代碼:

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

// 定義讀寫鎖結(jié)構(gòu)體
typedef struct rwlock {
    pthread_mutex_t lock;  // 互斥鎖,用于保護(hù)讀寫鎖的內(nèi)部狀態(tài)
    pthread_cond_t read_cond;  // 條件變量,用于讀操作的等待和通知
    pthread_cond_t write_cond;  // 條件變量,用于寫操作的等待和通知
    int read_count;  // 讀操作的計(jì)數(shù)
    int write_in_progress;  // 寫操作是否正在進(jìn)行的標(biāo)志
} rwlock_t;

// 初始化讀寫鎖
void rwlock_init(rwlock_t *rwlock) {
    // 初始化互斥鎖
    pthread_mutex_init(&rwlock->lock, NULL);
    // 初始化讀操作的條件變量
    pthread_cond_init(&rwlock->read_cond, NULL);
    // 初始化寫操作的條件變量
    pthread_cond_init(&rwlock->write_cond, NULL);
    // 初始時(shí)讀計(jì)數(shù)為 0
    rwlock->read_count = 0;
    // 初始時(shí)寫操作未進(jìn)行
    rwlock->write_in_progress = 0;
}

// 讀鎖加鎖
void rwlock_read_lock(rwlock_t *rwlock) {
    // 獲取互斥鎖
    pthread_mutex_lock(&rwlock->lock);
    // 若有寫操作正在進(jìn)行,讀線程等待
    while (rwlock->write_in_progress) {
        pthread_cond_wait(&rwlock->read_cond, &rwlock->lock);
    }
    // 讀計(jì)數(shù)增加
    rwlock->read_count++;
    // 釋放互斥鎖
    pthread_mutex_unlock(&rwlock->lock);
}

// 讀鎖解鎖
void rwlock_read_unlock(rwlock_t *rwlock) {
    // 獲取互斥鎖
    pthread_mutex_lock(&rwlock->lock);
    // 讀計(jì)數(shù)減少
    rwlock->read_count--;
    // 若讀計(jì)數(shù)為 0 且無(wú)寫操作正在進(jìn)行,通知寫線程
    if (rwlock->read_count == 0 && rwlock->write_in_progress == 0) {
        pthread_cond_signal(&rwlock->write_cond);
    }
    // 釋放互斥鎖
    pthread_mutex_unlock(&rwlock->lock);
}

// 寫鎖加鎖
void rwlock_write_lock(rwlock_t *rwlock) {
    // 獲取互斥鎖
    pthread_mutex_lock(&rwlock->lock);
    // 若有讀操作或?qū)懖僮髡谶M(jìn)行,寫線程等待
    while (rwlock->read_count > 0 || rwlock->write_in_progress) {
        pthread_cond_wait(&rwlock->write_cond, &rwlock->lock);
    }
    // 標(biāo)記寫操作正在進(jìn)行
    rwlock->write_in_progress = 1;
    // 釋放互斥鎖
    pthread_mutex_unlock(&rwlock->lock);
}

// 寫鎖解鎖
void rwlock_write_unlock(rwlock_t *rwlock) {
    // 獲取互斥鎖
    pthread_mutex_lock(&rwlock->lock);
    // 標(biāo)記寫操作結(jié)束
    rwlock->write_in_progress = 0;
    // 通知所有等待讀的線程
    pthread_cond_broadcast(&rwlock->read_cond);
    // 通知等待寫的線程
    pthread_cond_signal(&rwlock->write_cond);
    // 釋放互斥鎖
    pthread_mutex_unlock(&rwlock->lock);
}

// 讀線程的操作函數(shù)
void reader_function(rwlock_t *rwlock) {
    rwlock_read_lock(rwlock);
    printf("Reader is reading...\n");
    rwlock_read_unlock(rwlock);
}

// 寫線程的操作函數(shù)
void writer_function(rwlock_t *rwlock) {
    rwlock_write_lock(rwlock);
    printf("Writer is writing...\n");
    rwlock_write_unlock(rwlock);
}

int main() {
    rwlock_t rwlock;  // 定義讀寫鎖變量
    rwlock_init(&rwlock);  // 初始化讀寫鎖

    pthread_t reader1, reader2, writer;  // 定義線程變量

    // 創(chuàng)建讀線程 1
    pthread_create(&reader1, NULL, (void *)reader_function, &rwlock);
    // 創(chuàng)建讀線程 2
    pthread_create(&reader2, NULL, (void *)reader_function, &rwlock);
    // 創(chuàng)建寫線程
    pthread_create(&writer, NULL, (void *)writer_function, &rwlock);

    // 等待讀線程 1 結(jié)束
    pthread_join(reader1, NULL);
    // 等待讀線程 2 結(jié)束
    pthread_join(reader2, NULL);
    // 等待寫線程結(jié)束
    pthread_join(writer, NULL);

    return 0;
}

以下是對(duì)這段代碼的詳細(xì)解析:

1.包含頭文件

#include <pthread.h>:包含了 POSIX 線程庫(kù)的頭文件,用于多線程編程。

#include <stdio.h>:包含了標(biāo)準(zhǔn)輸入輸出頭文件,用于打印輸出。

2.定義讀寫鎖結(jié)構(gòu)體 rwlock_t

  • pthread_mutex_t lock:用于保護(hù)讀寫鎖內(nèi)部狀態(tài)的互斥鎖。

  • pthread_cond_t read_cond:用于讀操作等待和通知的條件變量。

  • pthread_cond_t write_cond:用于寫操作等待和通知的條件變量。

  • int read_count:記錄讀操作的數(shù)量。

  • int write_in_progress:標(biāo)志是否有寫操作正在進(jìn)行。

3.函數(shù)定義

  • rwlock_init 函數(shù):初始化讀寫鎖的各個(gè)成員,包括互斥鎖和條件變量,將讀計(jì)數(shù)設(shè)為0,寫標(biāo)志設(shè)為0。

  • rwlock_read_lock 函數(shù):獲取讀鎖。先獲取互斥鎖,若有寫操作正在進(jìn)行則等待,然后增加讀計(jì)數(shù),最后釋放互斥鎖。

  • rwlock_read_unlock 函數(shù):釋放讀鎖。先獲取互斥鎖,減少讀計(jì)數(shù),若讀計(jì)數(shù)為 0 且無(wú)寫操作正在進(jìn)行則通知寫線程,最后釋放互斥鎖。

  • rwlock_write_lock 函數(shù):獲取寫鎖。先獲取互斥鎖,若有讀操作或?qū)懖僮髡谶M(jìn)行則等待,然后設(shè)置寫標(biāo)志為 1,最后釋放互斥鎖。

  • rwlock_write_unlock 函數(shù):釋放寫鎖。先獲取互斥鎖,清除寫標(biāo)志,通知所有等待讀的線程和一個(gè)等待寫的線程,最后釋放互斥鎖。

  • reader_function 函數(shù):讀線程的執(zhí)行函數(shù),獲取讀鎖后打印信息然后釋放讀鎖。

  • writer_function 函數(shù):寫線程的執(zhí)行函數(shù),獲取寫鎖后打印信息然后釋放寫鎖。

4.main 函數(shù)

  • 定義讀寫鎖變量 rwlock 并初始化。

  • 定義線程變量 reader1、reader2 和 writer。

  • 創(chuàng)建兩個(gè)讀線程和一個(gè)寫線程,并分別指定執(zhí)行函數(shù)和傳遞讀寫鎖參數(shù)。

  • 使用 pthread_join 等待三個(gè)線程結(jié)束,確保程序不會(huì)提前退出。總的來(lái)說(shuō),這段代碼實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的讀寫鎖機(jī)制,通過(guò)多線程的方式展示了讀線程和寫線程對(duì)共享資源的同步訪問(wèn)。

編譯并執(zhí)行程序,結(jié)果如下:

[root@localhost rwlock]# gcc pthread_rwlock_st.c -o pthread_rwlock_st -lpthread
[root@localhost rwlock]# ls
pthread_rwlock  pthread_rwlock.c  pthread_rwlock_st  pthread_rwlock_st.c
[root@localhost rwlock]# ./pthread_rwlock_st
Reader is reading...
Reader is reading...
Writer is writing...

總結(jié)

讀寫鎖相比于傳統(tǒng)的互斥鎖(mutex)具有更高的并發(fā)性能,特別是在讀操作遠(yuǎn)多于寫操作的場(chǎng)景下。這是因?yàn)樽x寫鎖允許多個(gè)讀線程同時(shí)訪問(wèn)共享資源,從而減少了線程間的等待時(shí)間,提高了系統(tǒng)的整體吞吐量。

然而,讀寫鎖也有其局限性,例如在寫操作頻繁的場(chǎng)景下,由于寫操作的排他性,可能會(huì)導(dǎo)致大量的讀線程被阻塞,降低系統(tǒng)的并發(fā)性能。因此,在設(shè)計(jì)多線程應(yīng)用時(shí),選擇合適的同步機(jī)制是非常重要的。

責(zé)任編輯:武曉燕 來(lái)源: Linux二進(jìn)制
相關(guān)推薦

2024-06-28 08:45:58

2024-07-05 08:32:36

2010-01-21 11:27:30

linux多線程機(jī)制線程同步

2010-03-15 16:31:34

Java多線程

2011-11-23 10:09:19

Java線程機(jī)制

2024-07-25 11:53:53

2022-03-24 13:36:18

Java悲觀鎖樂(lè)觀鎖

2022-06-15 07:32:35

Lock線程Java

2023-06-09 07:59:37

多線程編程鎖機(jī)制

2025-03-31 00:01:12

2017-12-15 10:20:56

MySQLInnoDB同步機(jī)制

2019-05-27 14:40:43

Java同步機(jī)制多線程編程

2012-07-27 10:02:39

C#

2012-07-09 09:25:13

ibmdw

2023-10-08 09:34:11

Java編程

2016-09-20 15:21:35

LinuxInnoDBMysql

2010-01-21 11:22:35

Linux多線程同步

2010-01-21 11:23:49

Linux多線程同步消息隊(duì)列

2011-06-22 13:57:54

Java多線程

2011-06-22 13:47:16

Java多線程
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)