隊列與線程的關(guān)系
-
『ios』主線程 和 主隊列的關(guān)系颅痊,絕對安全的UI操作袜腥,主線程中一定是主隊列漆腌?
- (void)testInMainThread { // 異步提交任務(wù)到主隊列 dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"1 --- %@", [NSThread currentThread]); self.label.backgroundColor = [UIColor orangeColor]; // 正常 }); // 同步提交任務(wù)到自定義并發(fā)隊列 dispatch_sync(dispatch_queue_create("queue1", DISPATCH_QUEUE_CONCURRENT), ^{ NSLog(@"2 --- %@", [NSThread currentThread]); self.label.backgroundColor = [UIColor greenColor]; // 正常 }); // 同步提交任務(wù)到自定義串行隊列 dispatch_sync(dispatch_queue_create("queue2", DISPATCH_QUEUE_SERIAL), ^{ NSLog(@"3 --- %@", [NSThread currentThread]); self.label.backgroundColor = [UIColor whiteColor]; // 正常 }); } 2 --- <NSThread: 0x6000039a1400>{number = 1, name = main} 3 --- <NSThread: 0x6000039a1400>{number = 1, name = main} 1 --- <NSThread: 0x6000039a1400>{number = 1, name = main}
- 隊列不是線程畔派。隊列用來組織任務(wù)槐沼,線程是執(zhí)行隊列中的任務(wù)曙蒸。
- 主隊列是一個特殊的串行隊列捌治,異步提交任務(wù)到主隊列不會開辟新線程。
- 一個線程可以執(zhí)行多個隊列中的任務(wù)纽窟。
- 只要在主線程具滴,主隊列、自定義的串行/并發(fā)隊列任務(wù)都能夠刷新 UI师倔。
- 主隊列不一定在主線程執(zhí)行构韵,比如:人為調(diào)用 dispatch_main()。
死鎖
用 dispatch_sync 添加任務(wù)到它自己所在的
串行隊列
中就會造成死鎖趋艘。
死鎖的三個條件:
- dispatch_sync(同步)添加任務(wù)
- 串行隊列
- 添加的任務(wù)和 dispatch_sync 在同一個隊列
- (void)testInMainThread
{
// 情形 ①疲恢、dispatch_sync 自身在主隊列
dispatch_sync(dispatch_get_main_queue(), ^{
});
dispatch_queue_t queue = dispatch_queue_create("CONCURRENT", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
// 情形 ②、dispatch_sync 自身在 queue 隊列
dispatch_sync(queue, ^{
NSLog(@"222");
});
});
}
解決方案就是讓死鎖的三個條件中任意一個不滿足即可瓷胧。
讀寫安全方案
- 同一時間显拳,只允許一個線程執(zhí)行寫入操作
- 同一時間,許多個線程都執(zhí)行讀取操作
- 同一時間搓萧,不能既有寫入操作杂数,也有讀取操作
方案:
- dispatch_semaphore 信號量,缺陷是不能實現(xiàn)允許多個線程讀取操作
- dispatch_barrier_async 柵欄瘸洛,注意讀寫任務(wù)隊列必須是自己創(chuàng)建的并發(fā)隊列
- pthread_rwlock 讀寫鎖
數(shù)據(jù)競爭
多個線程并發(fā)執(zhí)行揍移,同一時間訪問同一塊數(shù)據(jù)(如同一個變量、對象反肋、文件等)那伐,就有可能出現(xiàn)數(shù)據(jù)競爭,從而導(dǎo)致數(shù)據(jù)錯亂石蔗。
線程同步
方案:
- 加鎖罕邀。多個線程使用同一把鎖,對訪問數(shù)據(jù)的關(guān)鍵代碼進行加鎖养距;
- OSSpinLock 自旋鎖
- os_unfair_lock 互斥鎖
- pthread_mutex 互斥鎖
- NSLock 互斥鎖
- NSRecursiveLock 遞歸鎖
- @synchronized
- 設(shè)置線程的最大并發(fā)數(shù)為 1
- 把多個線程放入串行隊列
其中方案 2 和 3 差不多诉探。