读写锁是多线程同步中的一个很有用的东东,区分开读者和写者,有助于效率的提升。
就好像是一个签名簿,写者相当于签名的人,读者相当于看签名簿的人,写签名簿的一群人需要排队,一个一个地签名,而读者不需要排队,他们可以一起看。当一群围观的正在看时,匆匆忙忙跑来一个签名的,大喊“让开,我要迟到了,让我签到”,于是大家让开让他签了名子,这说明了什么?
1.写者比读者优先级高,同时竞争读写锁的话,写者将获得锁。
2.写者必须一个一个地获得锁
3.而一群读者可以同时获得读写锁。
下面一段程序说明了这个道理。
编译: gcc -o a rwlock.c -lpthread
运行: ./a
#include <stdio.h> #include <pthread.h> #include <stdlib.h> #define THREADCNT 10 pthread_rwlock_t rwlock; //建立读写锁 int global_var = 1; void* reader(void* pvoid) { pthread_rwlock_rdlock(&rwlock); //读方式获取锁 sleep(1); printf("reader %d worked. global_var = %d\n", (int)pvoid, global_var); if(pthread_rwlock_unlock(&rwlock)) { printf("reader %d unlock error!\n", (int)pvoid); } return NULL; } void* writer(void* pvoid) { pthread_rwlock_wrlock(&rwlock); //写方式获得锁 sleep(1); printf("writer %d worked. global_var = %d\n", (int)pvoid, global_var++); if(pthread_rwlock_unlock(&rwlock)) { printf("writer %d unlock error!\n", (int)pvoid); } return NULL; } int main() { pthread_t reader_id, writer_id; pthread_attr_t threadattr; int i, rand; int readercnt = 1, writercnt = 1; int halfmax = RAND_MAX / 2; if(pthread_rwlock_init(&rwlock, NULL)) { //初始化读写锁 printf("initialize rwlock error!\n"); } pthread_rwlock_wrlock(&rwlock); pthread_attr_init(&threadattr); pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_DETACHED); for(i = 0; i < THREADCNT; i++) { rand = random(); if(rand < halfmax) { pthread_create(&reader_id, &threadattr, reader, (void*)readercnt); printf("Created reader %d\n", readercnt++); } else { pthread_create(&writer_id, &threadattr, writer, (void*)writercnt); printf("Created writer %d\n", writercnt++); } } pthread_rwlock_unlock(&rwlock); pthread_exit(0); return 0; }
运行结果:
Created writer 1 Created reader 1 Created writer 2 Created writer 3 Created writer 4 Created reader 2 Created reader 3 Created writer 5 Created reader 4 Created writer 6 writer 3 worked. global_var = 1 writer 4 worked. global_var = 2 writer 5 worked. global_var = 3 writer 2 worked. global_var = 4 writer 6 worked. global_var = 5 writer 1 worked. global_var = 6 reader 2 worked. global_var = 7 reader 3 worked. global_var = 7 reader 4 worked. global_var = 7 reader 1 worked. global_var = 7