1、概述
讀寫鎖與互斥量類似,不過讀寫鎖允許更高的並行性。互斥量要么是鎖住狀態,要么是不加鎖狀態,而且一次只有一個線程對其加鎖。讀寫鎖可以有三種狀態:讀模式下加鎖狀態,寫模式下加鎖狀態,不加鎖狀態。一次只有一個線程可以占有寫模式的讀寫鎖,但是多個線程可用同時占有讀模式的讀寫鎖。讀寫鎖也叫做共享-獨占鎖,當讀寫鎖以讀模式鎖住時,它是以共享模式鎖住的,當它以寫模式鎖住時,它是以獨占模式鎖住的。
2、讀寫鎖API
讀寫鎖的數據類型為pthread_rwlock_t。如果這個類型的某個變量是靜態分配的,那么可通過給它賦常值PTHREAD_RWLOCK_INITIALIZER來初始化它。
獲取和釋放讀寫鎖:
int pthread_rwlock_rdlock(pthread_rwlock_t *rwptr); //獲取一個讀出鎖
int pthread_rwlock_wrlock(pthread_rwlock_t *rwptr); //獲取一個寫入鎖
int pthread_rwlock_unlock(pthread_rwlock_t *rwptr); //釋放一個寫入鎖或者讀出鎖
都返回:成功時為0,出錯時為正的Exxx值
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwptr);
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwptr);
都返回:成功時為0,出錯時為正的Exxx值
讀寫鎖屬性:
int pthread_rwlock_init(pthread_rwlock_t *rwptr, const pthread_rwlockattr_t *attr)
int pthread_rwlock_destroy(pthread_rwlock_t *rwptr);
都返回:成功時為0,出錯時為正的Exxx值
int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);
int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr);
都返回:成功時為0,出錯時為正的Exxx值
int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr, int *valptr);
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int valptr);
都返回:成功時為0,出錯時為正的Exxx值
讀寫鎖在不同進程間共享:
PTHREAD_PROCESS_SHARED
線程取消
通過由對方調用函數pthread_cancel,一個線程可以被同一個進程內的任何其他線程所取消(cancel):
int pthread_cancel(pthread_t tid);
都返回:成功時為0,出錯時為正的Exxx值
為處理被取消的可能情況,任何線程可以安裝(壓入)和刪除(彈出)清理處理程序:
void pthread_cleanup_push(void (*function)(void *), void *arg);
void pthread_cleanup_pop(int execute);
這些處理程序就是發生以下情況時被調用的函數:
1. 調用線程被取消(有某個線程調用pthread_cancel完成)
2. 調用線程自願終止(或者通過調用pthread_exit,或者從自己的線程起始函數返回)
寫個程序實現讀者-寫者問題,程序如下:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <pthread.h> #include <errno.h> #define MAXDATA 1024 #define MAXREDER 100 #define MAXWRITER 100 struct { pthread_rwlock_t rwlock; //讀寫鎖 char datas[MAXDATA]; //共享數據域 }shared = { PTHREAD_RWLOCK_INITIALIZER }; void *reader(void *arg); void *writer(void *arg); int main(int argc,char *argv[]) { int i,readercount,writercount; pthread_t tid_reader[MAXREDER],tid_writer[MAXWRITER]; if(argc != 3) { printf("usage : <reader_writer> #<readercount> #<writercount>\n"); exit(0); } readercount = atoi(argv[1]); //讀者個數 writercount = atoi(argv[2]); //寫者個數 pthread_setconcurrency(readercount+writercount); for(i=0;i<writercount;++i) pthread_create(&tid_writer[i],NULL,writer,NULL); sleep(1); //等待寫者先執行 for(i=0;i<readercount;++i) pthread_create(&tid_reader[i],NULL,reader,NULL); //等待線程終止 for(i=0;i<writercount;++i) pthread_join(tid_writer[i],NULL); for(i=0;i<readercount;++i) pthread_join(tid_reader[i],NULL); exit(0); } void *reader(void *arg) { pthread_rwlock_rdlock(&shared.rwlock); //獲取讀出鎖 printf("Reader begins read message.\n"); printf("Read message is: %s\n",shared.datas); pthread_rwlock_unlock(&shared.rwlock); //釋放鎖 return NULL; } void *writer(void *arg) { char datas[MAXDATA]; pthread_rwlock_wrlock(&shared.rwlock); //獲取寫如鎖 printf("Writers begings write message.\n"); printf("Enter the write message: \n"); gets(datas); //寫入數據 strcat(shared.datas,datas); pthread_rwlock_unlock(&shared.rwlock); //釋放鎖 return NULL; }
程序執行結果如下所示:

