Linux執行緒同步機制三 讀寫鎖rwlock

2021-08-04 21:09:37 字數 4038 閱讀 2279

一、讀寫鎖基本原理

在對資料的讀寫應用中,很多情況是大量的讀操作,而寫操作較少,例如對資料庫資料的訪問。顯然使用互斥鎖將極大地影響效率。為滿足這一應用領域,posix執行緒提供了讀寫鎖機制,騎基本原則如下:

1.如果當前執行緒讀資料,則允許其他執行緒執行讀操作,但不允許寫操作

2.如果當前執行緒寫資料,則其他執行緒的讀、寫操作均不允許

因此,讀寫鎖分為了讀鎖寫鎖。具體如下所示:

1.如果某執行緒申請了讀鎖,其他執行緒可以再申請讀鎖,但不能申請寫鎖;

2.如果某執行緒申請了寫鎖,則其他執行緒不能申請讀鎖,也不能申請寫鎖。

二、讀寫鎖基本操作函式

讀寫鎖基本操作函式如下表所示:

1.初始化讀寫鎖

在使用讀寫鎖前,需要定義讀寫斥鎖(全域性變數),定義讀寫鎖的**入下:

pthread_rwlock_t rwlock;
pthread_rwlock_init()函式用於初始化讀寫鎖,其函式宣告為:

int pthread_rwlock_init(pthread_rwlock_t* rwlock, pthread_rwlockattr_t* attr);
第1個引數rwlock是指向要初始化的讀寫鎖的指標;

第2個引數attr指向屬性物件的指標,該屬性定義要初始化的讀寫鎖的特性,此引數設定為null時,則使用預設屬性。

函式執行成功是返回0,否則返回乙個錯誤編號,以指明錯誤。

下面是一段初始化讀寫鎖的**:

pthread_rwlock_t rwlock;

pthread_rwlockattr_tcattr;

int ret;

ret = pthread_rwlock_init(&cv, null); // 使用預設屬性初始化讀寫鎖

ret = pthread_rwlock_init(&cv, &cattr); // 使用自定義屬性初始化讀寫鎖

也可以使用巨集pthread_rwlock_initializer初始化靜態分配的讀寫鎖。這相當於呼叫pthread_rwlock_init()動態初始化時指定attr引數為null。區別在於,它不執行錯誤檢查。下面是使用此巨集初始化讀寫鎖**:

pthread_rwlock_t rwlock = pthread_rwlock_initializer;
2.申請讀鎖pthread_rwlock_rdlock()函式以阻塞的方式來申請讀鎖,其函式宣告如下:

int pthread_rwlock_rdlock(pthread_rwlock_t* rwlock);
pthread_rwlock_tryrdlock()函式以阻塞的方式來申請讀鎖,其函式宣告如下:

int pthread_rwlock_tryrdlock(pthread_rwlock_t* rwlock);
如果不能申請到鎖,pthread_rwlock_rdlock()將阻塞當前執行緒,而pthread_rwlock_tryrdlock()將返回錯誤。

兩函式執行成功時返回0。否則,返回錯誤編號以指明錯誤。

3.申請寫鎖

pthread_rwlock_wrlock()函式以阻塞的方式來申請讀鎖,其函式宣告如下:

int pthread_rwlock_wrlock(pthread_rwlock_t* rwlock);
pthread_rwlock_trywrlock()函式以阻塞的方式來申請讀鎖,其函式宣告如下:

int pthread_rwlock_trywrlock(pthread_rwlock_t* rwlock);
如果不能申請到鎖,pthread_rwlock_wrlock()將阻塞當前執行緒,而pthread_rwlock_trywrlock()將返回錯誤。

兩函式執行成功時返回0。否則,返回錯誤編號以指明錯誤(未設定errno變數)。

4.解鎖

無弄是讀鎖還是寫鎖都將使用函式pthread_rwlock_unlock()來釋放鎖,此函式宣告如下:

int pthread_rwlock_unlock(pthread_rwlock_t* rwlock);
使用此函式需要注意一下情況:

1.如果呼叫此函式來釋放讀鎖,但當前還有其他讀鎖定,則保持讀鎖定狀態,只不過當前執行緒已不再是其所有者之一。只有當最後乙個讀鎖釋放,則讀寫鎖將處於解鎖狀態。

2.如果呼叫此函式釋放寫鎖,則置讀寫鎖為解鎖狀態。

此函式執行成功時返回0。否則,返回錯誤編號以指明錯誤。

5.銷毀讀寫鎖

pthread_rwlock_destroy()函式用來銷毀讀寫鎖,其函式申明如下:

int pthread_rwlock_destroy(pthread_rwlock_t* rwlock);
引數rwlock指向要銷毀的讀寫鎖的指標。

函式執行成功時返回0。否則,返回錯誤編碼號以指明錯誤。

三、示例

下面通過4個執行緒對乙個全域性變數的操作來展示,其中2個執行緒是讀操作,2個執行緒是寫操作,**如下所示:

#include 

#include

int num = 0;

pthread_rwlock_t rwlock;

void* pth_read(void* arg)

pthread_exit(0);

}void* pth_write(void* arg)

pthread_exit(0);

}int main()

ret = pthread_create(&tid2, null, pth_read, "b");

if (0 != ret)

ret = pthread_create(&tid3, null, pth_write, "c");

if (0 != ret)

ret = pthread_create(&tid4, null, pth_write, "d");

if (0 != ret)

pthread_join(tid1, null);

pthread_join(tid2, null);

pthread_join(tid3, null);

pthread_join(tid4, null);

// 銷毀鎖

pthread_rwlock_destroy(&rwlock);

return

0;}

執行結果如下圖所示:

由上圖可知,在別的執行緒(a執行緒)持有讀鎖的時候,其他執行緒(b執行緒)還可以獲取到讀鎖。但只有當所有的讀鎖釋放後寫鎖才能持有。同樣只有當寫鎖釋放時,讀鎖才能獲取到鎖。

Linux 同步機制 讀寫鎖

讀寫鎖也叫 shared exclusive 鎖,也是一種同步機制。讀寫鎖有三種狀態 讀模式下加鎖,寫模式下加鎖,不加鎖。有如下的使用約定 讀模式共享,寫模式獨佔,適合讀頻率遠大於寫頻率的場景。這些api位於 pthread.h 下。initialize read write lock rwlock...

(4 3)Linux執行緒同步機制 讀寫鎖

1 問題描述 2 互斥關係 3 同步關係 1 在保證互斥的基礎上,linux 提供了對臨界資源訪問控制粒度更細的讀寫鎖機制 2 讀寫鎖機制可以實現如下訪問控制規則 3 讀寫鎖的操作與互斥量的操作非常類似 4 讀寫鎖的加鎖操作在互斥量加鎖的基礎上擴充套件,具有加讀鎖和加寫鎖兩種操作 標頭檔案 pthr...

執行緒同步機制《三》

三 執行緒同步機制分析 當多個執行緒同時啟動時,且這多個執行緒對同一資源進行操作時,會發生紊亂的現象。例項 如下 建立乙個執行緒1 public class thread1 extends thread public void run catch exception e 建立乙個執行緒2 publi...