美文网首页
iOS各种锁简介(上)

iOS各种锁简介(上)

作者: NotFound_XXX | 来源:发表于2018-01-03 13:21 被阅读0次

iOS各种锁简介(上)

本篇文章主要介绍iOS中几种不同的锁的实现方式,既然是简介,这里不会涉及到原理上面的东西,主要还是如何使用。

在开始之前,我们先构建一个测试类,假设这个类是一个共享资源,提供两个方法method1和method2,假设method1和method2是互斥的,代码如下:

@implementation TestObject

- (void)method1 {
    NSLog(@"%@",NSStringFromSelector(_cmd));
}

- (void)method2 {
    NSLog(@"%@",NSStringFromSelector(_cmd));
}

@end

NSLock

NSLock是cocoa提供给我们最基本的锁对象,这个是最简单的一个锁,NSLock提供了lock和unlock两个方法,分别是加锁和解锁。NSLock内部实际是封装了pthread_mutex。使用方法很简单,代码如下:

- (void)lockDemo {
    TestObject *obj = [[TestObject alloc] init];
    NSLock *lock = [[NSLock alloc] init];

    // 线程1
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [lock lock];
        [obj method1];
        sleep(10);
        [lock unlock];
    });

    // 线程2
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        sleep(1);
        [lock lock];
        [obj method2];
        [lock unlock];
    });
}

从打印结果可以看出,线程1获得锁之后,线程2会一直等待,直到线程1释放锁(unlock)之后才会执行。

@synchronized

@synchronized的使用方式很简单,先看代码:

- (void)synchronizedDemo {
    TestObject *obj = [[TestObject alloc] init];

    // 线程1
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        @synchronized(obj) {
            [obj method1];
            sleep(10);
        }
    });

    // 线程2
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        sleep(1);
        @synchronized(obj) {
            [obj method2];
        }
    });
}

跟NSLock加锁的结果一样,线程2也是等到线程1释放锁之后才执行。从代码中可以看出,@synchronized实现锁非常方便,注意:@synchronized指令中使用的obj为锁的唯一标识,只有标识相同的时候,才满足互斥。如果上述代码中线程2@synchronized(obj)中的标识和线程1的不一样,那么线程2不会被阻塞。

pthread_mutex_t

pthread_mutex_t是posix下的一个锁类型,如果熟悉linux c编程的话会对这个比较熟悉。在iOS下使用也是一样的,代码如下:

- (void)pthreadDemo {
    TestObject *obj = [[TestObject alloc] init];

    __block pthread_mutex_t mutex;
    pthread_mutex_init(&mutex, NULL);

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        pthread_mutex_lock(&mutex);
        [obj method1];
        sleep(5);
        pthread_mutex_unlock(&mutex);
    });

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        sleep(1);
        pthread_mutex_lock(&mutex);
        [obj method2];
        pthread_mutex_unlock(&mutex);
    });
}

注意: 由于pthread_mutex_t是posix下的API,所以要引入相应的头文件#import <pthread.h>

dispatch_semaphore_t

dispatch_semaphore_t是GCD里面的一个信号量机制,也可以用来做线程同步。其相关的方法主要有:

dispatch_semaphore_t dispatch_semaphore_create(long value);
long dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);
long dispatch_semaphore_signal(dispatch_semaphore_t dsema);

dispatch_semaphore_create:创建一个新的信号量,value代表信号量资源的数量.
dispatch_semaphore_wait: 等待资源释放,如果此时dsema大于0,获得资源,继续执行,并将信号量减1。如果dsema=0,阻塞当前线程直到其他线程调dispatch_semaphore_signal释放信号量。如果一直等不到信号量,则到timeout之后再继续执行。
dispatch_semaphore_signal:释放一个资源。

使用代码如下:

- (void)semaphoreDemo {
    TestObject *obj = [[TestObject alloc] init];

    dispatch_semaphore_t semphore = dispatch_semaphore_create(1);

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        dispatch_semaphore_wait(semphore, DISPATCH_TIME_FOREVER);
        [obj method1];
        sleep(5);
        dispatch_semaphore_signal(semphore);
    });

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        sleep(1);
        dispatch_semaphore_wait(semphore, DISPATCH_TIME_FOREVER);
        [obj method2];
        dispatch_semaphore_signal(semphore);
    });
}

相关文章

网友评论

      本文标题:iOS各种锁简介(上)

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