讀寫鎖是計算機(jī)程序的并發(fā)控制的一種同步機(jī)制,也稱“共享-互斥鎖”、多讀者-單寫者鎖。讀操作可并發(fā)重入,寫操作是互斥的。
實現(xiàn)原理
兩把互斥鎖
使用兩把互斥鎖與一個整數(shù)計數(shù)器實現(xiàn)。計數(shù)器condition跟蹤被阻塞的讀線程。互斥鎖rlock保護(hù)condition,供讀者使用。互斥鎖wlock 確保寫操作互斥。
#import "JKRWLock.h"
#import <pthread/pthread.h>
pthread_mutex_t rlock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t wlock = PTHREAD_MUTEX_INITIALIZER;
static int condition = 0;
@implementation JKRWLock
//讀者加鎖
- (void)rLock {
pthread_mutex_lock(&rlock);
condition++;
if (condition == 1) {
pthread_mutex_lock(&wlock);
}
pthread_mutex_unlock(&rlock);
}
//讀者解鎖
- (void)rUnlock {
pthread_mutex_lock(&rlock);
condition--;
if (condition == 0) {
pthread_mutex_unlock(&wlock);
}
pthread_mutex_unlock(&rlock);
}
//寫者加鎖
- (void)wLock {
pthread_mutex_lock(&wlock);
}
//寫者解鎖
- (void)wUnlock {
pthread_mutex_unlock(&wlock);
}
@end
條件變量+互斥鎖
可使用條件變量cond與普通的互斥鎖rwlock、整型計數(shù)器readCount(表示正在讀的個數(shù))與布爾標(biāo)志write(表示正在寫)來實現(xiàn)讀寫鎖。
#import "JKRWLock.h"
#import <pthread/pthread.h>
@interface JKRWLock ()
@property (nonatomic, assign) int readCount;
@property (nonatomic, assign, getter=isWriting) BOOL write;
@end
//讀寫鎖
pthread_mutex_t rwlock = PTHREAD_MUTEX_INITIALIZER;
//條件變量
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
@implementation JKRWLock
//讀者加鎖
- (void)rLock {
pthread_mutex_lock(&rwlock);
while (self.isWriting) {
pthread_cond_wait(&cond, &rwlock);
}
self.readCount++;
pthread_mutex_unlock(&rwlock);
}
//讀者解鎖
- (void)rUnlock {
pthread_mutex_lock(&rwlock);
self.readCount--;
if (self.readCount == 0) {
//喚起一條寫的線程
pthread_cond_signal(&cond);
}
pthread_mutex_unlock(&rwlock);
}
//寫者加鎖
- (void)wLock {
pthread_mutex_lock(&rwlock);
while (self.isWriting || self.readCount > 0) {
pthread_cond_wait(&cond, &rwlock);
}
self.write = YES;
pthread_mutex_unlock(&rwlock);
}
//寫者解鎖
- (void)wUnlock {
pthread_mutex_lock(&rwlock);
self.write = NO;
//喚起多個讀的線程
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&rwlock);
}
@end
同步任務(wù)+柵欄
讀數(shù)據(jù)
- (id)objectForKey:(NSString *)key {
__block id obj;
// 同步讀取指定數(shù)據(jù):
dispatch_sync(self.concurrent_queue, ^{
obj = [self.dataCenterDic objectForKey:key];
});
return obj;
}
寫數(shù)據(jù)
- (void)setObject:(id)obj forKey:(NSString *)key {
// 異步柵欄調(diào)用設(shè)置數(shù)據(jù):
dispatch_barrier_async(self.concurrent_queue, ^{
[self.dataCenterDic setObject:obj forKey:key];
});
}
總結(jié)
以上就是關(guān)于讀寫鎖的實現(xiàn)原理以及它的一些使用方式。如果你有更好的實現(xiàn)方式,歡迎私信我。