隊列與線程的關(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 差不多。