iOS多线程( 四)

思考如何实现以下场景

 同一时间,只能有一个线程进行写操作
 同一时间,允许有多个线程读操作
 同一时间,不允许既有写的操作又有读的操作

1.1代码实现一 dispatch_barrier_async

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    dispatch_queue_t queue = dispatch_queue_create("rwQueue", DISPATCH_QUEUE_CONCURRENT);
    for (int i=0; i<=10; i++) {
        dispatch_async(queue, ^{
            [self read];
        });
        
        dispatch_async(queue, ^{
            [self read];
        });
        
        dispatch_async(queue, ^{
            [self read];
        });
        //这个函数传入的并发队列必须是通过dispatch_queue_create创建的
       //这个传入的是一个串行或是一个全局的并发队列,那么这个函数就等于dispatch_aync函数的效果
        dispatch_barrier_async(queue, ^{
            [self write];
        });
    }
}

- (void)read {
    sleep(1);
    NSLog(@"read");
}

- (void)write {
    sleep(1);
    NSLog(@"write");
}

@end

1.2 原理

dispatch_barrier_async(queue, ^{
[self write];
});

dispatch_barrier_sync: Submits a barrier block object for execution and waits until that block completes.(提交一个栅栏函数在执行中,它会等待栅栏函数执行完)

dispatch_barrier_async: Submits a barrier block for asynchronous execution and returns immediately.(提交一个栅栏函数在异步执行中,它会立马返回)

作者理解:dispatch_barrier_sync 需要等待栅栏执行完才会执行栅栏后面的任务,而dispatch_barrier_async 无需等待栅栏执行完,会继续往下走(保留在队列里)

原因:在同步栅栏时栅栏函数在主线程中执行,而异步栅栏中开辟了子线程栅栏函数在子线程中执行

2.1代码实现 pthread_rwlock_t

#import "ViewController.h"
#import <pthread/pthread.h>

@interface ViewController ()
@property(nonatomic, assign) pthread_rwlock_t lock;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
   
    //初始化锁
    pthread_rwlock_init(&_lock, NULL);
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    for (int i=0; i<10; i++) {
        dispatch_async(queue, ^{
            [self read];
        });
        dispatch_async(queue, ^{
            [self write];
        });
    }
}

- (void)read {
    pthread_rwlock_rdlock(&_lock);
    sleep(1);
    NSLog(@"read");
    pthread_rwlock_unlock(&_lock);
}

- (void)write {
    pthread_rwlock_wrlock(&_lock);
    sleep(1);
    NSLog(@"write");
    pthread_rwlock_unlock(&_lock);
}

- (void)dealloc
{
    pthread_rwlock_destroy(&_lock);
}

@end

2.2原理:

//初始化锁
pthread_rwlock_t lock;
pthread_rwlock_init(&lock, NULL);
//读加锁
pthread_rwlock_rdlock(&lock);
//读尝试加锁
pthread_rwlock_tryrdlock(&lock);
//写加锁
pthread_rwlock_wrlock(&lock);
//写尝试加锁
pthread_rwlock_trywrlock(&lock);
//解锁
pthread_rwlock_unlock(&lock);
//销毁
pthread_rwlock_destroy(&lock);
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一. NSConditionLock NSConditionLock是对NSCondition的进一步封装,可以设...
    Imkata阅读 4,185评论 0 0
  • 一、GCD简介 iOS开发中多线程的API主要有pthread,NSThread,NSOperation和GC...
    shuaikun阅读 975评论 0 1
  • iOS中常见的多线程方案 pthread NSThread GCD NSOperation GCD GCD执行任务...
    lieon阅读 4,233评论 0 2
  • 目录: GCD 加锁方案 一. GCD 说一下iOS中多线程的实现方案 ① 这些多线程方案的底层都是依赖pthre...
    Imkata阅读 3,218评论 0 0
  • 前言 iOS开发中由于各种第三方库的高度封装,对锁的使用很少,刚好之前面试中被问到的关于并发编程锁的问题,都是一知...
    喵渣渣阅读 9,112评论 0 33