1、基本介绍
1.1、OSSpinLock
1.1.1、自旋锁,iOS10及以后版本已标记过期;
1.1.2、锁定状态下,其他线程访问时处于忙等状态
1.1.3、存在优先级反转的问题而被放弃;
1.2、os_unfair_lock
1.2.1、互斥锁
1.2.2、锁定状态下,其他线程访问时会处于休眠状态
1.3、pthread_mutex
1.3.1、互斥锁
1.3.2、可跨平台使用
2、代码实现
2.1、OSSpinLock
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | #import "ViewController.h" #import <libkern/OSAtomic.h> #import <os/lock.h> #import <pthread.h> @interface ViewController () { NSUInteger _ticketCount; // 剩余票数 OSSpinLock _spinLock; // Spin锁(自旋锁) } @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // 锁初始化 _spinLock = OS_SPINLOCK_INIT; // 同时开启两个异步线程对票数进行自减 _ticketCount = 20; // 创建一个并行队列 dispatch_queue_t queue = dispatch_queue_create("custom-queue", DISPATCH_QUEUE_CONCURRENT); dispatch_async(dispatch_get_global_queue(0, 0), ^{ for (int i = 0; i < 5; i++) { [self saleTicket]; } }); dispatch_async(dispatch_get_global_queue(0, 0), ^{ for (int i = 0; i < 5; i++) { [self saleTicket]; } }); } - (void)saleTicket { // 1、线程加锁 OSSpinLockLock(&_spinLock); // 2、执行 NSUInteger remain = _ticketCount; // 2.1、先取数据,休眠1秒后再写入,通过窗口期制造写入冲突 sleep(1); _ticketCount = --remain; NSLog(@"%ld, %@", _ticketCount, [NSThread currentThread]); // 3、解锁 OSSpinLockUnlock(&_spinLock); } |
打印输出:
加锁前:
2018-11-26 16:28:44.022292+0800 MultiThread[8426:1133657] 19, <NSThread: 0x600000290400>{number = 3, name = (null)} 2018-11-26 16:28:44.022322+0800 MultiThread[8426:1133656] 19, <NSThread: 0x60000029d0c0>{number = 4, name = (null)} 2018-11-26 16:28:44.022581+0800 MultiThread[8426:1133657] 18, <NSThread: 0x600000290400>{number = 3, name = (null)} 2018-11-26 16:28:44.022625+0800 MultiThread[8426:1133656] 18, <NSThread: 0x60000029d0c0>{number = 4, name = (null)} 2018-11-26 16:28:44.022749+0800 MultiThread[8426:1133656] 16, <NSThread: 0x60000029d0c0>{number = 4, name = (null)} 2018-11-26 16:28:44.022735+0800 MultiThread[8426:1133657] 17, <NSThread: 0x600000290400>{number = 3, name = (null)} 2018-11-26 16:28:44.022851+0800 MultiThread[8426:1133656] 15, <NSThread: 0x60000029d0c0>{number = 4, name = (null)} 2018-11-26 16:28:44.022860+0800 MultiThread[8426:1133657] 14, <NSThread: 0x600000290400>{number = 3, name = (null)} 2018-11-26 16:28:44.023016+0800 MultiThread[8426:1133657] 13, <NSThread: 0x600000290400>{number = 3, name = (null)} 2018-11-26 16:28:44.024139+0800 MultiThread[8426:1133656] 12, <NSThread: 0x60000029d0c0>{number = 4, name = (null)} |
加锁后:
2018-11-26 15:43:17.603606+0800 MultiThread[6545:997594] 19, <NSThread: 0x600002e06e80>{number = 3, name = (null)} 2018-11-26 15:43:17.603914+0800 MultiThread[6545:997594] 18, <NSThread: 0x600002e06e80>{number = 3, name = (null)} 2018-11-26 15:43:17.604286+0800 MultiThread[6545:997594] 17, <NSThread: 0x600002e06e80>{number = 3, name = (null)} 2018-11-26 15:43:17.604444+0800 MultiThread[6545:997594] 16, <NSThread: 0x600002e06e80>{number = 3, name = (null)} 2018-11-26 15:43:17.604581+0800 MultiThread[6545:997594] 15, <NSThread: 0x600002e06e80>{number = 3, name = (null)} 2018-11-26 15:43:17.605013+0800 MultiThread[6545:997592] 14, <NSThread: 0x600002e02cc0>{number = 4, name = (null)} 2018-11-26 15:43:17.605168+0800 MultiThread[6545:997592] 13, <NSThread: 0x600002e02cc0>{number = 4, name = (null)} 2018-11-26 15:43:17.605287+0800 MultiThread[6545:997592] 12, <NSThread: 0x600002e02cc0>{number = 4, name = (null)} 2018-11-26 15:43:17.605406+0800 MultiThread[6545:997592] 11, <NSThread: 0x600002e02cc0>{number = 4, name = (null)} 2018-11-26 15:43:17.605522+0800 MultiThread[6545:997592] 10, <NSThread: 0x600002e02cc0>{number = 4, name = (null)} |
2.2、os_unfair_lock、pthread_mutex
2.2.1、os_unfair_lock
1 2 3 4 5 6 7 8 9 | // 1、初始化 os_unfair_lock unfair_lock = OS_UNFAIR_LOCK_INIT; // 2、加锁 os_unfair_lock_lock(&unfair_lock); // coding..... // 3、解锁 os_unfair_lock_unlock(&unfair_lock); |
2.2.2、pthread_mutex
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | // 1.1、初始化锁属性 pthread_mutexattr_t pthread_mutexattr; pthread_mutexattr_init(&pthread_mutexattr); pthread_mutexattr_settype(&pthread_mutexattr, PTHREAD_MUTEX_DEFAULT); // 递归锁 // pthread_mutexattr_settype(&pthread_mutexattr, PTHREAD_MUTEX_RECURSIVE); // 1.2、初始化锁 pthread_mutex_t pthread_mutex; pthread_mutex_init(&pthread_mutex, &pthread_mutexattr); pthread_mutexattr_destroy(&pthread_mutexattr); // 2、加锁 pthread_mutex_lock(&pthread_mutex); // coding..... // 3、解锁 pthread_mutex_unlock(&pthread_mutex); |
Pingback: 基于pthread_mutex封装的锁NSLock、NSCondition、NSConditionLock、NSRecursiveLock、@Synchronized | 一天到晚游泳的余
条件锁的基本实现
1、在特定逻辑条件中添加条件锁,此时会临时解锁;
2、其他线程可对此锁进行加锁操作;
3、当接收到唤醒信号时,条件锁会重新加锁执行;
4、示例代码:
5、打印结果:
递归锁的简单实现: