ios实现读写锁,AFN的实现

读写锁场景:

同一时间,只能有1个线程进行写的操作

同一时间,允许有多个线程进行读的操作

同一时间,不允许既有写的操作,又有读的操作

 

 上面的场景就是典型的“多读单写”,经常用于文件等数据的读写操作,iOS中的实现方案有:

1、读写锁:pthread_rwlock

等待锁的线程会进入休眠

ios实现读写锁,AFN的实现_第1张图片


2、dispatch_barrier_async

这个函数传入的并发队列必须是自己通过dispatch_queue_cretate创建的,全局队列不可以


#import "ViewController.h"

@interface ViewController ()

@property (nonatomic, copy) NSString *text;
@property (nonatomic, strong) dispatch_queue_t concurrentQueue;

@end


@implementation ViewController

@synthesize text = _text;

- (void)viewDidLoad {
    [super viewDidLoad];


    [self readWriteLock];    

}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [self readWriteLock];

}

- (void)readWriteLock {
    
    self.concurrentQueue = dispatch_queue_create("aaa", DISPATCH_QUEUE_CONCURRENT);
    // 测试代码,模拟多线程情况下的读写
    for (int i = 0; i<10; i++) {
        
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            self.text = [NSString stringWithFormat:@"噼里啪啦--%d",i];
        });
        
    }
    
    for (int i = 0; i<50; i++) {
        
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            NSLog(@"读 %@ %@",[self text],[NSThread currentThread]);
        });
        
    }
    
    
    for (int i = 10; i<20; i++) {
        
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            self.text = [NSString stringWithFormat:@"噼里啪啦--%d",i];
        });
        
    }
}

// 写操作,栅栏函数是不允许并发的,所以"写操作"是单线程进入的,根据log可以看出来
- (void)setText:(NSString *)text {
    
    __weak typeof(self) weakSelf = self;
    dispatch_barrier_sync(self.concurrentQueue, ^{
        __strong typeof(weakSelf) strongSelf = weakSelf;
        strongSelf->_text = text;
        NSLog(@"写操作 %@ %@",text,[NSThread currentThread]);
        // 模拟耗时操作,1个1个执行,没有并发
        sleep(1);
    });
}
// 读操作,这个是可以并发的,log在很快时间打印完
- (NSString *)text {

    __block NSString * t = nil ;
    __weak typeof(self) weakSelf = self;
    dispatch_sync(self.concurrentQueue, ^{
        __strong typeof(weakSelf) strongSelf = weakSelf;
        t = strongSelf->_text;
        // 模拟耗时操作,瞬间执行完,说明是多个线程并发的进入的
        sleep(1);

    });
    return t;

}

@end

参考了Effective Objective-C . 书上用了全局队列,算是书上的一个小bug吧.

ios实现读写锁,AFN的实现_第2张图片

ios实现读写锁,AFN的实现_第3张图片

下面在贴上一个AFN的实现 , requestHeaderModificationQueue是一个由AFHTTPRequestSerializer创建的并发队列, 使用这个并发队列对一个NSMutableDictionary实现了多读单写的锁.

    /// 并发队列
    self.requestHeaderModificationQueue = dispatch_queue_create("requestHeaderModificationQueue", DISPATCH_QUEUE_CONCURRENT);

ios实现读写锁,AFN的实现_第4张图片

 

你可能感兴趣的:(ios实现读写锁,AFN的实现)