美文网首页
17-线程同步方案

17-线程同步方案

作者: weyan | 来源:发表于2019-03-11 13:17 被阅读0次

    线程同步本质:不能让多条线程同时占用一份资源。

    一、OSSpinLock(高级锁)

    线程阻塞:

    • 外循环:是一直占用着CPU资源。
    • 线程休眠:该线程就不占用CPU资源。

    static修饰的变量不能用调用函数进行初始化,因为函数调用是在运行过程中调用的,static修饰的变量初始化是在编译时就确定的。

    不要看到多线程调用同一个方法或访问同一个变量就加锁,要视情况而定。

    二、os_unfair_lock (互斥锁、低级锁)

    死锁:永远拿不到锁(加锁后没有解锁)。

    三、pthread_mutex(低级锁)

    • 递归锁(PTHREAD_MUTEX_RECURSIVE):同一个线程对一把锁可以重复加锁。
    • pthread_mutex条件

    四、自旋锁、互斥锁的汇编分析:

    • 自旋锁汇编:
    • 互斥锁汇编:

    五、NSLock、NSRecursiveLock、NSCondition

    • NSLock
    #import "NSLockDemo.h"
    
    @interface NSLockDemo()
    @property (strong, nonatomic) NSLock *ticketLock;
    @property (strong, nonatomic) NSLock *moneyLock;
    @end
    
    @implementation NSLockDemo
    
    
    - (instancetype)init
    {
        if (self = [super init]) {
            self.ticketLock = [[NSLock alloc] init];
            self.moneyLock = [[NSLock alloc] init];
        }
        return self;
    }
    
    // 死锁:永远拿不到锁
    - (void)__saleTicket
    {
        [self.ticketLock lock];
        
        [super __saleTicket];
        
        [self.ticketLock unlock];
    }
    
    • NSRecursiveLock
      使用方法和NSLock一样。

    • NSCondition

    #import "NSConditionDemo.h"
    
    @interface NSConditionDemo()
    @property (strong, nonatomic) NSCondition *condition;
    @property (strong, nonatomic) NSMutableArray *data;
    @end
    
    @implementation NSConditionDemo
    
    - (instancetype)init
    {
        if (self = [super init]) {
            self.condition = [[NSCondition alloc] init];
            self.data = [NSMutableArray array];
        }
        return self;
    }
    
    - (void)otherTest
    {
        [[[NSThread alloc] initWithTarget:self selector:@selector(__remove) object:nil] start];
        
        [[[NSThread alloc] initWithTarget:self selector:@selector(__add) object:nil] start];
    }
    
    // 生产者-消费者模式
    
    // 线程1
    // 删除数组中的元素
    - (void)__remove
    {
        [self.condition lock];
        NSLog(@"__remove - begin");
        
        if (self.data.count == 0) {
            // 等待
            [self.condition wait];
        }
        
        [self.data removeLastObject];
        NSLog(@"删除了元素");
        
        [self.condition unlock];
    }
    
    // 线程2
    // 往数组中添加元素
    - (void)__add
    {
        [self.condition lock];
        
        sleep(1);
        
        [self.data addObject:@"Test"];
        NSLog(@"添加了元素");
        // 信号
        [self.condition signal];
        
        // 广播
    //    [self.condition broadcast];
        [self.condition unlock];
        
    }
    @end
    
    • NSConditionLock
    #import "NSConditionLockDemo.h"
    
    @interface NSConditionLockDemo()
    @property (strong, nonatomic) NSConditionLock *conditionLock;
    @end
    
    @implementation NSConditionLockDemo
    
    - (instancetype)init
    {
        if (self = [super init]) {
            //创建锁并设置锁的条件值为1
            self.conditionLock = [[NSConditionLock alloc] initWithCondition:1];
        }
        return self;
    }
    
    - (void)otherTest
    {
        [[[NSThread alloc] initWithTarget:self selector:@selector(__one) object:nil] start];
        
        [[[NSThread alloc] initWithTarget:self selector:@selector(__two) object:nil] start];
        
        [[[NSThread alloc] initWithTarget:self selector:@selector(__three) object:nil] start];
    }
    
    - (void)__one
    {
         //根据锁的条件值进行加锁,否则线程处于休眠状态。
        [self.conditionLock lockWhenCondition:1];
    
        //直接加锁,不用根据条件值
         //[self.conditionLock lock];
        NSLog(@"__one");
        sleep(1);
        //解锁,并设置锁的条件值为2。
        [self.conditionLock unlockWithCondition:2];
    }
    
    - (void)__two
    {
        [self.conditionLock lockWhenCondition:2];
        
        NSLog(@"__two");
        sleep(1);
        
        [self.conditionLock unlockWithCondition:3];
    }
    
    - (void)__three
    {
        [self.conditionLock lockWhenCondition:3];
        
        NSLog(@"__three");
        
        [self.conditionLock unlock];
    }
    
    @end
    

    六、SerialQueue

    七、dispatch_semaphore

    #import "SemaphoreDemo.h"
    
    @interface SemaphoreDemo()
    @property (strong, nonatomic) dispatch_semaphore_t semaphore;
    @property (strong, nonatomic) dispatch_semaphore_t ticketSemaphore;
    @property (strong, nonatomic) dispatch_semaphore_t moneySemaphore;
    @end
    
    @implementation SemaphoreDemo
    
    - (instancetype)init
    {
        if (self = [super init]) {
            //设置信号量
            self.semaphore = dispatch_semaphore_create(5);
            self.ticketSemaphore = dispatch_semaphore_create(1);
            self.moneySemaphore = dispatch_semaphore_create(1);
        }
        return self;
    }
    
    - (void)__drawMoney
    {
        dispatch_semaphore_wait(self.moneySemaphore, DISPATCH_TIME_FOREVER);
        
        [super __drawMoney];
        
        dispatch_semaphore_signal(self.moneySemaphore);
    }
    
    - (void)__saveMoney
    {
        dispatch_semaphore_wait(self.moneySemaphore, DISPATCH_TIME_FOREVER);
        
        [super __saveMoney];
        
        dispatch_semaphore_signal(self.moneySemaphore);
    }
    
    - (void)__saleTicket
    {
        dispatch_semaphore_wait(self.ticketSemaphore, DISPATCH_TIME_FOREVER);
        
        [super __saleTicket];
        
        dispatch_semaphore_signal(self.ticketSemaphore);
    }
    
    - (void)otherTest
    {
        for (int i = 0; i < 20; i++) {
            [[[NSThread alloc] initWithTarget:self selector:@selector(test) object:nil] start];
        }
    }
    
    // 线程10、7、6、9、8
    - (void)test
    {
        // 如果信号量的值 > 0,就让信号量的值减1,然后继续往下执行代码
        // 如果信号量的值 <= 0,就会休眠等待,直到信号量的值变成>0,就让信号量的值减1,然后继续往下执行代码
        dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
        
        sleep(2);
        NSLog(@"test - %@", [NSThread currentThread]);
        
        // 让信号量的值+1
        dispatch_semaphore_signal(self.semaphore);
    }
    
    @end
    

    八、@synchronized

    九、线程同步方案性能对比

    自旋锁、互斥锁的比较

    十、atomic和nonatomic

    十一、读写安全

    • pthread_rwlock

    • dispatch_barrier_async


      ßß

    相关文章

      网友评论

          本文标题:17-线程同步方案

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