【C/C++多執行緒程式設計之九】pthread讀寫鎖

Love_Hulidear發表於2014-05-04

多執行緒程式設計之讀寫鎖


     Pthread是 POSIX threads 的簡稱,是POSIX的執行緒標準
        pthread讀寫鎖把對共享資源的訪問者分為讀者寫者,讀者只對共享資源進行讀訪問,寫者只對共享資源進行寫操作。在互斥機制,讀者和寫者都需要獨立獨佔互斥量以獨佔共享資源,在讀寫鎖機制下,允許同時有多個讀者讀訪問共享資源,只有寫者才需要獨佔資源。相比互斥機制,讀寫機制由於允許多個讀者同時讀訪問共享資源,進一步提高了多執行緒的併發度。
         
       1.讀寫鎖機制

       寫者:寫者使用寫鎖,如果當前沒有讀者,也沒有其他寫者,寫者立即獲得寫鎖;否則寫者將等待,直到沒有讀者和寫者。
       讀者:讀者使用讀鎖,如果當前沒有寫者,讀者立即獲得讀鎖;否則讀者等待,直到沒有寫者。
           
          2.讀寫鎖特性

        同一時刻只有一個執行緒可以獲得寫鎖,同一時刻可以有多個執行緒獲得讀鎖。
        讀寫鎖出於寫鎖狀態時,所有試圖對讀寫鎖加鎖的執行緒,不管是讀者試圖加讀鎖,還是寫者試圖加寫鎖,都會被阻塞。
       讀寫鎖處於讀鎖狀態時,有寫者試圖加寫鎖時,之後的其他執行緒的讀鎖請求會被阻塞,以避免寫者長時間的不寫鎖。
        
        3.讀寫鎖基本函式
         # include<pthread.h>
讀寫鎖初始化:
        int pthread_rwlock_init(pthread_rwlock_t * rwlock, 
                                                 const pthread_rwlockattr_t *  attr);
        該函式第一個引數為讀寫鎖指標,第二個引數為讀寫鎖屬性指標。函式按讀寫鎖屬性對讀寫鎖進行初始化。
加讀鎖:
        int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
        該函式引數為讀寫鎖指標。函式用於對讀寫鎖加讀鎖。
加寫鎖:
        int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
        該函式引數為讀寫鎖指標。函式用於對讀寫鎖加寫鎖。
釋放讀寫鎖:
        int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
        該函式引數為讀寫鎖指標。函式用於釋放讀寫鎖,包括讀鎖與寫鎖。
銷燬讀寫鎖:
        int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
        該函式引數為讀寫鎖指標。函式用於銷燬讀寫鎖。

        4.牛刀小試
        示例使用讀寫鎖,對共享資源data進行讀寫同步,執行緒readerM,readerN為讀者執行緒,執行緒writerA,writerB為寫者執行緒。       
#include 
#include 
#include 
#include 
#pragma comment(lib, "pthreadVC2.lib")     //必須加上這句
pthread_t t1;           //pthread_t變數t1,用於獲取執行緒1的ID
pthread_t t2;           //pthread_t變數t2,用於獲取執行緒2的ID
pthread_rwlock_t rwlock;             //宣告讀寫鎖
int data=1;                          //共享資源
void* readerM(void* arg)
{
	while(1)
	{
	pthread_rwlock_rdlock(&rwlock);    //讀者加讀鎖
	printf("M 讀者讀出: %d \n",data);   //讀取共享資源
	pthread_rwlock_unlock(&rwlock);    //讀者釋放讀鎖
	Sleep(1200);
	}
	return NULL;
}
void* readerN(void* arg)
{
	while(1)
	{
	pthread_rwlock_rdlock(&rwlock);
	printf(" N讀者讀出: %d \n",data);
	pthread_rwlock_unlock(&rwlock);
	Sleep(700);
	}
	return NULL;
}
void* writerA(void* arg)
{
	while(1)
	{
	pthread_rwlock_wrlock(&rwlock);      //寫者加寫鎖
	data++;                              //對共享資源寫資料
	printf("	A寫者寫入: %d\n",data);
	pthread_rwlock_unlock(&rwlock);      //釋放寫鎖
	Sleep(2000);
	}
	return NULL;
}
void* writerB(void* arg)
{
	while(1)
	{
	pthread_rwlock_wrlock(&rwlock);
	 data++;
	printf("	B寫者寫入: %d\n",data);
	pthread_rwlock_unlock(&rwlock);
	Sleep(2000);
	}
	return NULL;
}
void main(int argc,char** argv)
{
	pthread_rwlock_init(&rwlock, NULL);   //初始化讀寫鎖
    
    pthread_create(&t1,NULL,readerM,NULL);
	pthread_create(&t1,NULL,readerN,NULL);
	pthread_create(&t2,NULL,writerA,NULL);
	pthread_create(&t2,NULL,writerB,NULL);

	pthread_rwlock_destroy(&rwlock);      //銷燬讀寫鎖

	Sleep(10000000);
	return;
}

相關文章