iOS 原理探究-讀寫鎖

讀寫鎖是計算機(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)方式,歡迎私信我。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。