pthread_rwlock


讀寫鎖

 

 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值

 

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 #include <unistd.h>
 5 #include <pthread.h>
 6 #include <errno.h>
 7 
 8 #define MAXDATA     1024
 9 #define MAXREDER    100
10 #define MAXWRITER   100
11 struct
12 {
13     pthread_rwlock_t   rwlock; 
14     char datas[MAXDATA];    
15 } shared = { 
16     PTHREAD_RWLOCK_INITIALIZER
17 };
18 
19 void *reader(void *arg);
20 void *writer(void *arg);
21 
22 int main(int argc,char *argv[])
23 {
24     int i,readercount,writercount;
25     pthread_t tid_reader[MAXREDER],tid_writer[MAXWRITER];
26     if(argc != 3)
27     {   
28         printf("usage : <reader_writer> #<readercount> #<writercount>\n");
29         exit(0);
30     }   
31     readercount = atoi(argv[1]);  
32     writercount = atoi(argv[2]);
33     pthread_setconcurrency(readercount+writercount);
34     for(i=0;i<writercount;++i)
35         pthread_create(&tid_writer[i],NULL,writer,NULL);
36     sleep(1);
37     for(i=0;i<readercount;++i)
38         pthread_create(&tid_reader[i],NULL,reader,NULL);
39     for(i=0;i<writercount;++i)
40         pthread_join(tid_writer[i],NULL);
41     for(i=0;i<readercount;++i)
42         pthread_join(tid_reader[i],NULL);
43     exit(0);
44 }
45 void *reader(void *arg)
46 {
47     pthread_rwlock_rdlock(&shared.rwlock);
48     printf("Reader begins read message.\n");
49     sleep(1);
50     printf("Read message is: %s\n",shared.datas);
51     pthread_rwlock_unlock(&shared.rwlock);
52     return NULL;
53 }
54 
55 void *writer(void *arg)
56 {
57     char datas[MAXDATA];
58     pthread_rwlock_wrlock(&shared.rwlock);
59     printf("Writers begings write message.\n");
60     printf("Enter the write message: \n");
61     gets(datas);
62     strcat(shared.datas,datas);
63     pthread_rwlock_unlock(&shared.rwlock);
64     return NULL;
65 }

 

打印輸出

[root@localhost pthread_rwlock]# ./run 5 1
Writers begings write message.
Enter the write message: 
sdfs
Reader begins read message.
Reader begins read message.
Reader begins read message.
Reader begins read message.
Reader begins read message.
Read message is: sdfs
Read message is: sdfs
Read message is: sdfs
Read message is: sdfs
Read message is: sdfs
[root@localhost pthread_rwlock]# 

我在read中加入sleep,看家其他read線程也進入了,表明一次只有一個線程可以占有寫模式的讀寫鎖,但是多個線程可用同時占有讀模式的讀寫鎖。

 另外請關注pthread_setconcurrency();

 最近在code review一些人的代碼的時候,發現了一個問題,就是很少人關注pthread_setconcurrency()函數,其實這個函數在pthread中是一個很重要的函數。在linux下,如果你忽略了這個函數的使用,那么能夠並發的線程數目由實現者來控制,對於系統調度的效率而言往往不是什么好的事情,因為默認的設置往往不是最佳的。
     更為糟糕的是,如果在某些系統中,如果你不調用pthread_setconcurrency()函數,那么系統中的運行的線程僅僅是第一個被創建的線程,其他線程根本不會被運行。比如在solaris 2。6中就有這些情況。為了在unix或者是linux系統上使移植更加的容易,請不要忘記在適當的地方調用次函數,清晰的告訴系統我們使用的線程個數。雖然在某些系統上,這個調用是徒勞的,但是它的使用增強的移植性!

 

 


免責聲明!

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



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