美文网首页iOS进阶
iOS 原理探究-读写锁

iOS 原理探究-读写锁

作者: Joker_King | 来源:发表于2020-03-07 13:13 被阅读0次

    读写锁是计算机程序的并发控制的一种同步机制,也称“共享-互斥锁”、多读者-单写者锁。读操作可并发重入,写操作是互斥的。

    实现原理

    两把互斥锁

    使用两把互斥锁与一个整数计数器实现。计数器condition跟踪被阻塞的读线程。互斥锁rlock保护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、整型计数器readCount(表示正在读的个数)与布尔标志write(表示正在写)来实现读写锁。

    #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
    

    同步任务+栅栏

    读数据

    - (id)objectForKey:(NSString *)key {
        __block id obj;
        // 同步读取指定数据:
        dispatch_sync(self.concurrent_queue, ^{
            obj = [self.dataCenterDic objectForKey:key];
        });
        return obj;
    }
    

    写数据

    - (void)setObject:(id)obj forKey:(NSString *)key {
        // 异步栅栏调用设置数据:
        dispatch_barrier_async(self.concurrent_queue, ^{
            [self.dataCenterDic setObject:obj forKey:key];
        });
    }
    

    总结

    以上就是关于读写锁的实现原理以及它的一些使用方式。如果你有更好的实现方式,欢迎私信我。

    相关文章

      网友评论

        本文标题:iOS 原理探究-读写锁

        本文链接:https://www.haomeiwen.com/subject/bcxcdhtx.html