iOS開發系列-線程同步技術
阿新 • • 發佈:2018-08-25
%d syn rec 互斥鎖 body 排序 解決 nta 加鎖
概述
多線程的本質就是CPU輪流隨機分配給每條線程時間片資源執行任務,看起來多條線程同時執行任務。
多條線程同時訪問同一塊資源,比如操作同一個對象、統一變量、同一個文件,就會引發數據錯亂和數據安全
的問題。
多線程引發問題實例
這裏我也借助網上兩個比較經典的案例,賣票和存取錢。
賣票案例
多個線程同時賣票,同一時間多個線層同時訪問票的總數,就會引發數據錯亂。
實例代碼
@interface ViewController () @property (nonatomic, assign) int tickets; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.tickets = 30; [self saleTicketTest]; } - (void)saleTicketWithName:(NSString *)name { int currTicketCount = self.tickets; sleep(.2); currTicketCount--; self.tickets = currTicketCount; NSLog(@"當前%@賣了一張,票還剩:%d張", name ,self.tickets); } - (void)saleTicketTest { dispatch_queue_t queue = dispatch_get_global_queue(0, 0); dispatch_async(queue, ^{ for (int i=0; i<10; i++) { [self saleTicketWithName:@"A"]; } }); dispatch_async(queue, ^{ for (int i=0; i<10; i++) { [self saleTicketWithName:@"B"]; } }); dispatch_async(queue, ^{ for (int i=0; i<10; i++) { [self saleTicketWithName:@"C"]; } }); } @end
異常結果:
存錢取錢案例
實例代碼
#import "ViewController.h" @interface ViewController () @property (nonatomic, assign) int currMoney; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.currMoney = 1000; [self moneyTest]; } - (void)moneyTest { dispatch_async(dispatch_get_global_queue(0, 0), ^{ for (int i=0; i<4; i++) { [self saveMoney]; } }); dispatch_async(dispatch_get_global_queue(0, 0), ^{ for (int i=0; i<4; i++) { [self drawMoney]; } }); } // 存錢 - (void)saveMoney { int money = self.currMoney; sleep(.3); money += 100; self.currMoney = money; NSLog(@"存了100,還剩%d元", self.currMoney); } // 取錢 - (void)drawMoney { int money = self.currMoney; sleep(.3); money -= 50; self.currMoney = money; NSLog(@"取了50,還剩%d元", self.currMoney); }
異常結果:
多線程安全隱患的解決方案
開發中解決多線程安全隱患的方案-使用線程同步技術。同步(協同步調,按預定的先後順序執行)
常見的線程同步技術就是加鎖
。
iOS中線程同步的方案根據性能優先級排序:
線程同步的方案 | 需要導入頭文件 | 類別 | 註意事項 |
---|---|---|---|
os_unfair_lock | <os/lock.h> | 互斥鎖 | iOS10才開始提供,用來替代OSSpinLock |
OSSpinLock | <libkern/OSAtomic.h> | 自旋鎖 | 目前不在安全,可能會出現優先級反轉問題 |
dispatch_semaphore | |||
pthread_mutex | |||
dispatch_queue(DISPATCH_SENTINEL) | |||
NSLock | |||
oNSCondition | <os/lock.h> | ||
pthread_mutex(recuresive) | |||
NSRecursiveLock | |||
NSConditionLock | |||
@synchronized |
iOS開發系列-線程同步技術