美文网首页
多线程-锁

多线程-锁

作者: Michael_涵 | 来源:发表于2019-04-01 17:36 被阅读0次

Quick Start Guide

  1. @synchronized
  2. NSLock 对象锁
  3. NSRecursiveLock 递归锁
  4. NSConditionLock 条件锁
  5. pthread_mutex 互斥锁
  6. dispatch_semaphore 信号量锁
  7. OSSpinLock

性能对比

这里只能反应单线程情况,不能反映多线程下的实际性能

2208956-4a024a1c6c6214db.png

Getting Started

1. @synchronized

@synchronized(obj) {
  //这里obj指oc对象,一般为self
}

注意:加锁的代码量要少,oc对象在多个线程都是同一个对象

2. NSLock

//创建锁
NSLock *lock = [[NSLock alloc] init];
...
[lock lock];
//逻辑处理
[lock unlock];

注意:lock不能多次调用,会造成死锁

3. NSRecursiveLock

//死锁-递归
NSLock *lock = [[NSLock alloc] init];
dispatch_async(self.queue, ^{
  static void (^method)(int value);
  method = ^(int number) {
      [lock lock];
      //条件
      method(number)
      [lock unlock];
  };
  method(10);
});

//正确使用-递归
NSLock *lock = [[NSRecursiveLock alloc] init];
__block int num = 10;
dispatch_async(self.queue, ^{
  static void (^method)(int value);
  method = ^(int number) {
      [lock lock];
      //条件
      method(--number)
      [lock unlock];
  };
  method(num);
});

NSRecursiveLock在递归或者循环内(同一线程)使用不会造成死锁

4. NSConditionLock

NSConditionLock *lock = [[NSConditionLock alloc] init];

//线程1
dispatch_async(self.queue, ^{
  for (int i=0;i<10;i++) {
    [lock lock];
    NSLog(@"%d",i);
    [lock unlockWithCondition:5];
  }
});
//线程2
dispatch_async(self.queue, ^{
  [lock lockWhenCondition:5];
  [lock unlock];
});

5. pthread_mutex

//引用
#include <pthread.h>

//通过设置attr类型可以设置递归锁,互斥锁等
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL)

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

dispatch_async(self.queue, ^{
  pthread_mutex_lock(&mutex);
  NSLog(@"thread 1");
  pthread_mutex_unlock(&mutex);
});

dispatch_async(self.queue, ^{
  pthread_mutex_lock(&mutex);
  NSLog(@"thread 2");
  pthread_mutex_unlock(&mutex);
});

此方法比较基础,如NSLock,NSConditionLock,,NSRecursiveLock底层实现都是用此方法实现

6. dispatch_semaphore

//创建信号量,并设置初始信号总量
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
dispatch_queue_t queue = dispatch_queue_create("testqueue", DISPATCH_QUEUE_SERIAL);

dispatch_async(queue, ^{
   //模拟耗时操作
   [NSThread sleepForTimeInterval:2];
  //使总信号量减1,当信号总量为0时会一直等待,否则正常执行
  dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
  NSLog(@"thread 1");
  //发送一个信号,让信号总量加1
  dispatch_semaphore_signal(semaphore);
});

dispatch_async(queue, ^{
  dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
  NSLog(@"thread 2");
  dispatch_semaphore_signal(semaphore);
});

7. OSSpinLock

//创建锁
lock = OS_SPINLOCK_INIT;
...
//加锁
OSSpinLockLock(&lock);
...
//解锁
OSSpinLockUnlock(&lock);

不推荐使用,如果一个低优先级的线程获得锁并访问共享资源,这时一个高优先级的线程也尝试获得这个锁,它会处于 spin lock 的忙等状态从而占用大量 CPU。此时低优先级线程无法与高优先级线程争夺 CPU 时间,从而导致任务迟迟完不成、无法释放 lock。这并不只是理论上的问题,libobjc 已经遇到了很多次这个问题了,于是苹果的工程师停用了 OSSpinLock。ios 10以后可以使用os_unfair_lock代替OSSpinLock

相关文章

  • 起底多线程同步锁(iOS)

    起底多线程同步锁(iOS) 起底多线程同步锁(iOS)

  • 浅析乐观锁、悲观锁与CAS

    乐观锁与悲观锁 处理多线程并发访问最常用的就是加锁,锁又分成乐观锁和悲观锁。 悲观锁 在多线程访问共享资源时,同时...

  • 多线程与锁

    多线程与锁

  • 多线程 (三)iOS中的锁

    ios 多线程--锁

  • 多线程(四)

    上篇多线程(三)我们看了多线程的安全隐患 以及各种锁的简单使用,接下来我们来看看锁的比较、以及自旋锁、互斥锁比较 ...

  • 解决线程同步的方案汇总总结

    这是一篇继上一篇继续介绍多线程同步的博客.(你了解多线程自旋锁、互斥锁、递归锁等锁吗?[https://www.j...

  • OC--各种线程锁

    参考:正确使用多线程同步锁@synchronized()iOS中的锁iOS多线程安全详解iOS 常见知识点(三):...

  • zookeeperDistributedLock

    分布式锁: 分布式锁是什么? 通常说的锁是单进程多线程的锁,在多线程并发编程中用于线程之间的数据共享 分布式锁 指...

  • 锁与多线程同步的实现

    Java当中的锁都是为了保证多线程同步执行。如果没有锁的话,多线程是异步执行的。 什么是多线程同步? 请看下面的代...

  • iOS线程同步

    线程同步 提到多线程大家肯定会提到锁,其实真正应该说的是多线程同步,锁只是多线程同步的一部分。 多线程对于数据处理...

网友评论

      本文标题:多线程-锁

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