转载:http://blog.csdn.net/ojshilu/article/details/25244389
对于某个临界资源的访问,读操作和写操作是要区别对待的。读操作可以多个线程同时进行,写操作必须互斥进行。
读写锁:当已经被加了读锁时,其他的读模式锁请求仍然可以访问,但是写模式锁不能访问;当写模式锁加锁时,其他的请求都不能访问。
本文尝试用四种方法来完成读写锁的操作,都包含有写模式和读模式各自所要做的事情。
1、直接使用POSIX提供的读写锁
2、用条件变量实现读写锁
3、用互斥量实现读写锁
4、用信号量实现读写锁
直接使用读写锁
pthread中直接为我们提供的。
- #include <pthread.h> //多线程、读写锁所需头文件
-
- pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
-
- 写模式:
- pthread_rwlock_wrlock(&rwlock);
- 写写写……
- pthread_rwlock_unlock(&rwlock);
-
-
-
- 读模式:
- pthread_rwlock_rdlock(&rwlock);
- 读读读……
- pthread_rwlock_unlock(&rwlock);
用条件变量实现读写锁
这里用条件变量+互斥锁来实现。注意:条件变量必须和互斥锁一起使用,等待、释放的时候都需要加锁。
- #include <pthread.h> //多线程、互斥锁所需头文件
-
- pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
- pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
-
-
- 写模式:
- pthread_mutex_lock(&mutex);
- while(w != 0 || r > 0)
- {
- pthread_cond_wait(&cond, &mutex);
- }
- w = 1;
-
- pthread_mutex_unlock(&mutex);
- 写写写……
- pthread_mutex_lock(&mutex);
- w = 0;
- pthread_cond_broadcast(&cond);
- pthread_mutex_unlock(&mutex);
-
-
- 读模式:
- pthread_mutex_lock(&mutex);
- while(w != 0)
- {
- pthread_cond_wait(&cond, &mutex);
- }
- r++;
- pthread_mutex_unlock(&mutex);
- 读读读……
- pthread_mutex_lock(&mutex);
- r- -;
- if(r == 0)
- pthread_cond_broadcast(&cond);
- pthread_mutex_unlock(&mutex);
用互斥锁实现读写锁
这里使用2个互斥锁+1个整型变量来实现。
- #include <pthread.h> //多线程、互斥锁所需头文件
- pthread_mutex_t r_mutex = PTHREAD_MUTEX_INITIALIZER;
- pthread_mutex_t w_mutex = PTHREAD_MUTEX_INITIALIZER;
- int readers = 0;
-
- 写模式:
- pthread_mutex_lock(&w_mutex);
- 写写写……
- pthread_mutex_unlock(&w_mutex);
-
-
- 读模式:
- pthread_mutex_lock(&r_mutex);
-
- if(readers == 0)
- pthread_mutex_lock(&w_mutex);
- readers++;
- pthread_mutex_unlock(&r_mutex);
- 读读读……
- pthread_mutex_lock(&r_mutex);
- readers- -;
- if(reader == 0)
- pthread_mutex_unlock(&w_mutex);
- pthread_mutex_unlock(&r_mutex);
用信号量来实现读写锁
这里使用2个信号量+1个整型变量来实现。令信号量的初始数值为1,那么信号量的作用就和互斥量等价了。
- #include <semaphore.h> //线程信号量所需头文件
-
- sem_t r_sem;
- sem_init(&r_sem, 0, 1);
-
- sem_t w_sem;
- sem_init(&w_sem, 0, 1);
- int readers = 0;
-
- 写模式:
- sem_wait(&w_sem);
- 写写写……
- sem_post(&w_sem);
-
-
- 读模式:
- sem_wait(&r_sem);
- if(readers == 0)
- sem_wait(&w_sem);
- readers++;
- sem_post(&r_sem);
- 读读读……
- sem_wait(&r_sem);
- readers- -;
- if(readers == 0)
- sem_post(&w_sem);
- sem_post(&r_sem);