iOS 开发 Objective-C

iOS 底层 day21 多线程锁 os_unfair_lock

2020-09-16  本文已影响0人  望穿秋水小作坊

一、 os_unfair_lock

1. os_unfair_lock 简介
2. os_unfair_lock 主要方法介绍
os_unfair_lock
3. os_unfair_lock 代码演示
#import "OSUnFairLockDemo.h"
#import <os/lock.h>

@interface OSUnFairLockDemo ()
@property(nonatomic, assign) os_unfair_lock ticketLock;
@property(nonatomic, assign) os_unfair_lock moneyLock;
@end

@implementation OSUnFairLockDemo
- (instancetype)init
{
    self = [super init];
    if (self) {
        self.ticketLock = OS_UNFAIR_LOCK_INIT;
        self.moneyLock = OS_UNFAIR_LOCK_INIT;
    }
    return self;
}
- (void)__saleTicket {
    os_unfair_lock_lock(&_ticketLock);
    [super __saleTicket];
    os_unfair_lock_unlock(&_ticketLock);
}
- (void)__saveMoney {
    os_unfair_lock_lock(&_moneyLock);
    [super __saveMoney];
    os_unfair_lock_unlock(&_moneyLock);
}
- (void)__drawMoney {
    os_unfair_lock_lock(&_moneyLock);
    [super __drawMoney];
    os_unfair_lock_unlock(&_moneyLock);
}
@end

二、 pthread_mutex

1. pthread_mutex 简介
2. pthread_mutex 主要方法介绍
pthread_mutex
3. pthread_mutex 代码演示
#import "PthreadMutexDemo.h"
#import <pthread.h>

@interface PthreadMutexDemo ()
@property(nonatomic, assign)pthread_mutex_t ticketMutex;
@property(nonatomic, assign)pthread_mutex_t monetMutex;
@end

@implementation PthreadMutexDemo

- (void) __initMutex:(pthread_mutex_t *)mutex{
    // 初始化锁的属性
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
    pthread_mutex_init(mutex, &attr);
    
    pthread_mutexattr_destroy(&attr);
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        [self __initMutex:&_ticketMutex];
        [self __initMutex:&_monetMutex];
    }
    return self;
}

- (void)__saleTicket {
    pthread_mutex_lock(&_ticketMutex);
    [super __saleTicket];
    pthread_mutex_unlock(&_ticketMutex);
}

- (void)__saveMoney {
    pthread_mutex_lock(&_monetMutex);
    [super __saveMoney];
    pthread_mutex_unlock(&_monetMutex);
}

- (void)__drawMoney {
    pthread_mutex_lock(&_monetMutex);
    [super __drawMoney];
    pthread_mutex_unlock(&_monetMutex);
}

- (void)dealloc {
    pthread_mutex_destroy(&_ticketMutex);
    pthread_mutex_destroy(&_monetMutex);
}

@end

三、 pthread_mutex 递归锁

1. pthread_mutex 递归锁简介
2. os_unfair_lock 代码演示
- (void) __otherFunc {
    pthread_mutex_lock(&_recursiveMutex);
    static int invokeCount = 0;
    
    if (invokeCount < 10) {
        invokeCount++;
        sleep(1.0);
        NSLog(@"%d %@",invokeCount, [NSThread currentThread]);
        [self __otherFunc];
    }
    pthread_mutex_unlock(&_recursiveMutex);
}

四、 pthread_mutex 添加条件

1. pthread_mutex 添加条件简介
2. 问题展示
- (void)__remove {
    [self.mutableArray removeLastObject];
    NSLog(@"__remove:%@",self.mutableArray);
}

- (void)__add {
    [self.mutableArray addObject:@"11"];
    NSLog(@"__add:%@",self.mutableArray);
}


- (void)otherTest {
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    dispatch_async(queue, ^{
        [self __remove];
    });
    dispatch_async(queue, ^{
        [self __add];
    });
}
3. pthread_mutex 添加条件代码演示
#import "PthreadMutexDemo2.h"
#import <pthread.h>

@interface PthreadMutexDemo2 ()
@property(nonatomic, assign)pthread_mutex_t mutex;
@property(nonatomic, assign)pthread_cond_t cond;
@property(nonatomic, strong)NSMutableArray *mutableArray;
@end

@implementation PthreadMutexDemo2

- (instancetype)init
{
    self = [super init];
    if (self) {
        
        // 初始化锁的属性
        pthread_mutexattr_t attr;
        pthread_mutexattr_init(&attr);
        pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
        pthread_mutex_init(&_mutex, &attr);
        
        // 初始化锁的条件
        pthread_cond_init(&_cond, NULL);
        
        self.mutableArray = [NSMutableArray array];
    }
    return self;
}


- (void)__remove {
    pthread_mutex_lock(&_mutex);
    if (self.mutableArray.count == 0) {
        pthread_cond_wait(&_cond, &_mutex);
    }
    [self.mutableArray removeLastObject];
    NSLog(@"__remove:%@",self.mutableArray);
    pthread_mutex_unlock(&_mutex);
}

- (void)__add {
    pthread_mutex_lock(&_mutex);
    [self.mutableArray addObject:@"11"];
    NSLog(@"__add:%@",self.mutableArray);
//    pthread_cond_broadcast(&_cond);
    pthread_cond_signal(&_cond);
    pthread_mutex_unlock(&_mutex);
}


- (void)otherTest {
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    dispatch_async(queue, ^{
        [self __remove];
    });
    dispatch_async(queue, ^{
        sleep(1.0);
        [self __add];
    });
}

@end

五、 NSLock NSCondition

六、 从汇编角度观察 OSSpinLock 、os_unfair_lock 和 pthread_mutex 等待锁的逻辑

1. OSSpinLock
2. os_unfair_lock
3. pthread_mutex

七、 YYBaseDemo 是封装了前面存取钱卖票例子的代码

#import "YYBaseDemo.h"

@interface YYBaseDemo ()
@property(nonatomic, assign) int moneyCount;
@property(nonatomic, assign) int ticketsCount;
@end

@implementation YYBaseDemo

- (void)moneyTest {
    self.moneyCount = 1000;
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    dispatch_async(queue, ^{
        for (int i = 0 ; i < 10; i++) {
        [self __drawMoney];
        }
    });
    
    dispatch_async(queue, ^{
        for (int i = 0 ; i < 10; i++) {
        [self __saveMoney];
        }
    });
    
}

- (void)__drawMoney {
    int readCount = self.moneyCount;
    sleep(0.2); //模拟网络拥堵
    int remainCount = readCount - 100;
    self.moneyCount = remainCount;
    NSLog(@"存钱---%@---剩余:%d",[NSThread currentThread], remainCount);
}

- (void)__saveMoney {
    int readCount = self.moneyCount;
    sleep(0.2); //模拟网络拥堵
    int remainCount = readCount + 200;
    self.moneyCount = remainCount;
    NSLog(@"取钱---%@---剩余:%d",[NSThread currentThread], remainCount);
}

- (void)ticketTest {
    self.ticketsCount = 20;
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 10; i++) {
            [self __saleTicket];
        }
    });
    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self __saleTicket];
        }
    });
    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self __saleTicket];
        }
    });
}

- (void)__saleTicket {
    int readCount = self.ticketsCount;
    sleep(0.2); //模拟网络拥堵
    int remainCount = readCount - 1;
    self.ticketsCount = remainCount;
    NSLog(@"卖票---%@---剩余:%d",[NSThread currentThread], remainCount);
}

- (void)otherTest{
    
}
@end
上一篇下一篇

猜你喜欢

热点阅读