iOS--GCD的常見用法,group、barrier、semaphore
專案中用到了阿里雲上傳,有20張圖片加3個音訊加視訊檔案,用到了GCD的東西,總結了一下。
程式碼地址:https://github.com/SunshineTraveller/LMGCDTEST
凌晨五點了 直接上程式碼吧還是 有註釋
總結:
////////////////////// GCD 總結 /////////////////////////////
一、同步:1.1不區分序列或併發,和佇列建立數目無關,都是在一個執行緒中執行。測試中任務在主執行緒中進行,會阻塞執行緒
二、非同步:2.1區分序列和併發
2.1.1 序列:一個佇列只會建立一個子執行緒,執行緒中的任務會按順序依次執行,任務之間是有等待的,後面的任務會等前面的任務完成後再去執行,不會阻塞執行緒
多個佇列會建立多個子執行緒,每個執行緒的任務相對無序執行,任務之間沒有等待,所有任務之間沒有相互約束
2.1.2 併發:和佇列數無關,n個任務會建立n個子執行緒,所有任務之間沒有等待,不存在相互約束
三、組: group裡的任務會在執行完後通過後通過通知回撥(區分同步任務和非同步任務!)
3.1 group裡執行的是同步任務(sync)
dispatch_group_async(dispatch_group_t group,dispatch_queue_t queue,dispatch_block_t block);
3.1.1 特點:group組會在放入group的佇列裡執行的任務會在全部任務執行完畢後通過dispatch_group_notify回撥,告知外界group裡的任務已經全部執行完畢,然後才會執行其他任務,group的佇列會根據任務數建立對應的執行緒數,n個任務就會有n個執行緒,並且是按順序執行的
3.2 group裡執行的是非同步任務(async)
!此時需要注意了,若為非同步任務,若不做任何處理,所有任務的執行和通知會同時執行,需要新增
四、 barrier:就像屏障一樣,隔開屏障前後的任務
4.1 dispatch_barrier_async 同步若同步執行佇列,任務有序執行,且barrier後面的任務會在barrier前的任務執行完後才會去執行
4.2 dispatch_barrier_sync 非同步若非同步執行佇列,任務無序執行,會開啟新執行緒且任務數多於執行緒數,barrier後面的任務會在barrier裡的任務執行完後才會去執行
五、訊號量 semaphore:記住一點即可!當訊號總量 <0的時候,它的wait方法便會暫停,直到訊號總量 >= 0的時候才會執行wait下面的方法,訊號量增加的方法就是signal那個方法!
dispatch_semaphore_wait:英文註釋:Decrement the counting semaphore. If the resulting value is less than zero,this function waits for a signal to occur before returning.
大致翻譯:減掉訊號量的總數,若減去後的結果值小於0,則該函式在返回之前會等待一個訊號傳送
keypoint: 1. dispatch_semaphore_wait函式會在訊號量總數小於0的時候開始等待(tip:大於0則不會等待),wait後的所有任務都不會執行,直到訊號量總數大於0。可以通過 dispatch_semaphore_signal 傳送訊號來增加訊號量總數,一旦訊號量總數大於0,wait函式就會結束等待,後面的任務就會開始執行
//////////////////////////////////////////////////////////////
/**
* 同步序列和佇列數無關,不會開啟新執行緒,會阻塞當前執行緒
* 本次測試在主執行緒中
*/
- (IBAction)syncSerial:(id)sender {
dispatch_queue_t sync_serial_queue =dispatch_queue_create("sync_serial_queue",DISPATCH_QUEUE_SERIAL);
dispatch_queue_t sync_serial_queue2 =dispatch_queue_create("sync_serial_queue2",DISPATCH_QUEUE_SERIAL);
dispatch_queue_t sync_serial_queue3 =dispatch_queue_create("sync_serial_queue3",DISPATCH_QUEUE_SERIAL);
dispatch_sync(sync_serial_queue, ^{
[NSThreadsleepForTimeInterval:3];
NSLog(@"syncSerial 1: *** %@",[NSThreadcurrentThread]);
});
dispatch_sync(sync_serial_queue2, ^{
[NSThreadsleepForTimeInterval:3];
NSLog(@"syncSerial 2: *** %@",[NSThreadcurrentThread]);
});
dispatch_sync(sync_serial_queue3, ^{
[NSThreadsleepForTimeInterval:3];
NSLog(@"syncSerial 3: *** %@",[NSThreadcurrentThread]);
});
NSLog(@"syncSerial測試 ");
}
控制檯:
2017-09-22 05:15:12.047 LMGCDTest[4937:384806] syncSerial 1: *** <NSThread: 0x174265580>{number = 1, name = main}
2017-09-22 05:15:15.049 LMGCDTest[4937:384806] syncSerial 2: *** <NSThread: 0x174265580>{number = 1, name = main}
2017-09-22 05:15:18.051 LMGCDTest[4937:384806] syncSerial 3: *** <NSThread: 0x174265580>{number = 1, name = main}
2017-09-22 05:15:18.052 LMGCDTest[4937:384806] syncSerial 測試
/**
* 同步併發不會開啟新執行緒,會阻塞當前執行緒,任務不會同時開始
*/
- (IBAction)syncConcurrent:(id)sender {
dispatch_queue_t sync_concurrent =dispatch_queue_create("sync_concurrent",DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t sync_concurrent2 =dispatch_queue_create("sync_concurrent2",DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t sync_concurrent3 =dispatch_queue_create("sync_concurrent3",DISPATCH_QUEUE_CONCURRENT);
dispatch_sync(sync_concurrent, ^{
NSLog(@"sync_concurrent 1: *** %@",[NSThreadcurrentThread]);
[NSThreadsleepForTimeInterval:3];
});
dispatch_sync(sync_concurrent2, ^{
NSLog(@"sync_concurrent 2: *** %@",[NSThreadcurrentThread]);
[NSThreadsleepForTimeInterval:3];
});
dispatch_sync(sync_concurrent3, ^{
NSLog(@"sync_concurrent 3: *** %@",[NSThreadcurrentThread]);
[NSThreadsleepForTimeInterval:3];
});
NSLog(@"sync_concurrent測試 ");
}
控制檯:
2017-09-22 05:15:53.169 LMGCDTest[4954:385224] sync_concurrent 1: *** <NSThread: 0x17407d800>{number = 1, name = main}
2017-09-22 05:15:56.171 LMGCDTest[4954:385224] sync_concurrent 2: *** <NSThread: 0x17407d800>{number = 1, name = main}
2017-09-22 05:15:59.173 LMGCDTest[4954:385224] sync_concurrent 3: *** <NSThread: 0x17407d800>{number = 1, name = main}
2017-09-22 05:16:02.175 LMGCDTest[4954:385224] sync_concurrent測試
/**
* 非同步序列一個佇列只會建立一個執行緒,佇列裡的任務會按順序執行(序列),不會阻塞執行緒
* 非同步序列 n個佇列建立n個執行緒,各佇列裡的任務併發無序執行,不會阻塞執行緒
*/
- (IBAction)asyncSerial:(id)sender {
dispatch_queue_t async_Serial =dispatch_queue_create("async_Serial",DISPATCH_QUEUE_SERIAL);
dispatch_queue_t async_Serial2 =dispatch_queue_create("async_Serial2",DISPATCH_QUEUE_SERIAL);
dispatch_queue_t async_Serial3 =dispatch_queue_create("async_Serial3",DISPATCH_QUEUE_SERIAL);
dispatch_async(async_Serial, ^{
[NSThreadsleepForTimeInterval:3];
NSLog(@"async_concurrent 1: *** %@",[NSThreadcurrentThread]);
});
dispatch_async(async_Serial2, ^{
[NSThreadsleepForTimeInterval:3];
NSLog(@"async_concurrent 2: *** %@",[NSThreadcurrentThread]);
});
dispatch_async(async_Serial3, ^{
[NSThreadsleepForTimeInterval:3];
NSLog(@"async_concurrent 3: *** %@",[NSThreadcurrentThread]);
});
NSLog(@"async_Serial測試 ");
}
控制檯:
2017-09-22 05:17:22.529 LMGCDTest[4968:385500] async_Serial測試
2017-09-22 05:17:25.531 LMGCDTest[4968:385714] async_concurrent 2: *** <NSThread: 0x1702662c0>{number = 3, name = (null)}
2017-09-22 05:17:25.531 LMGCDTest[4968:385712] async_concurrent 1: *** <NSThread: 0x174274a80>{number = 2, name = (null)}
2017-09-22 05:17:25.532 LMGCDTest[4968:385713] async_concurrent 3: *** <NSThread: 0x170266dc0>{number = 4, name = (null)}
/**
* 非同步併發
* 和佇列數無關,n個任務會建立n個執行緒,任務無序併發執行,不阻塞當前執行緒
*/
- (IBAction)asyncConcurrent:(id)sender {
dispatch_queue_t asyncConcurrent =dispatch_queue_create("asyncConcurrent",DISPATCH_QUEUE_CONCURRENT);
dispatch_async(asyncConcurrent, ^{
[NSThreadsleepForTimeInterval:3];
NSLog(@"asyncConcurrent 1: *** %@",[NSThreadcurrentThread]);
});
dispatch_async(asyncConcurrent, ^{
[NSThreadsleepForTimeInterval:3];
NSLog(@"asyncConcurrent 2: *** %@",[NSThreadcurrentThread]);
});
dispatch_async(asyncConcurrent, ^{
[NSThreadsleepForTimeInterval:3];
NSLog(@"asyncConcurrent 3: *** %@",[NSThreadcurrentThread]);
});
NSLog(@"asyncConcurrent測試 ");
}
控制檯:
2017-09-22 05:17:42.997 LMGCDTest[4968:385500] asyncConcurrent測試
2017-09-22 05:17:46.003 LMGCDTest[4968:385754] asyncConcurrent 2: *** <NSThread: 0x17426d2c0>{number = 6, name = (null)}
2017-09-22 05:17:46.003 LMGCDTest[4968:385753] asyncConcurrent 1: *** <NSThread: 0x17026e900>{number = 5, name = (null)}
2017-09-22 05:17:46.005 LMGCDTest[4968:385755] asyncConcurrent 3: *** <NSThread: 0x17426f200>{number = 7, name = (null)}
/*
* group裡執行的是同步任務,併發按次序執行任務,每個任務都會在新執行緒中執行
* group裡的任務完成後會回撥通知
**/
- (IBAction)group:(id)sender {
/* 1. group裡執行的是同步任務 */
// dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// dispatch_queue_t queue = dispatch_queue_create("sieral_queue", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t queue =dispatch_queue_create("sieral_queue",DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t queue1 =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
dispatch_group_t group_t =dispatch_group_create();
// 放在組中組中執行的都是同步任務
dispatch_group_async(group_t, queue, ^{
dispatch_sync(queue, ^{
NSLog(@"group_sync task 1: %@",[NSThreadcurrentThread]);
[NSThreadsleepForTimeInterval:3];
});
});
dispatch_group_async(group_t, queue, ^{
dispatch_sync(queue, ^{
NSLog(@"group_sync task 2: %@",[NSThreadcurrentThread]);
[NSThreadsleepForTimeInterval:3];
});
});
dispatch_group_async(group_t, queue, ^{
dispatch_sync(queue, ^{
NSLog(@"group_sync task 3: %@",[NSThreadcurrentThread]);
[NSThreadsleepForTimeInterval:3];
});
});
// 前三個任務完成後再去執行其他任務
dispatch_group_notify(group_t, queue1, ^{
NSLog(@"前三個同步任務執行完畢收到通知,執行第四個,group_task 4: %@",[NSThreadcurrentThread]);
[NSThreadsleepForTimeInterval:3];
});
NSLog(@"group sync Test");
}
控制檯:
2017-09-22 05:18:06.217 LMGCDTest[4968:385500] group sync Test
2017-09-22 05:18:06.219 LMGCDTest[4968:385773] group_sync task 1: <NSThread: 0x174269640>{number = 8, name = (null)}
2017-09-22 05:18:06.220 LMGCDTest[4968:385786] group_sync task 2: <NSThread: 0x170276d40>{number = 9, name = (null)}
2017-09-22 05:18:06.221 LMGCDTest[4968:385787] group_sync task 3: <NSThread: 0x17026a340>{number = 10, name = (null)}
2017-09-22 05:18:09.227 LMGCDTest[4968:385787] 前三個同步任務執行完畢收到通知,執行第四個,group_task 4: <NSThread: 0x17026a340>{number = 10, name = (null)}
/**
* group裡執行的是非同步任務,此時需要加 ‘進入enter’和‘離開leave’組,否則通知回撥會立即執行
* 任務執行時enter 任務完成後leave
* 若任務結束時不在當前方法內,設定group為全域性變數即可
*/
- (IBAction)group_async:(id)sender {
/** 2.group中執行的是非同步任務,需要引入entre和leave */
dispatch_group_t group_t2 =dispatch_group_create();
dispatch_queue_t queue_t2 =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
dispatch_queue_t queue_t2_1 =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
// 進入group_t2組(進入組和離開組必須成對出現,否則會造成死鎖)
dispatch_group_enter(group_t2);
// 組裡的任務都是非同步任務
dispatch_group_async(group_t2, queue_t2, ^{
dispatch_async(queue_t2, ^{
NSLog(@"group_async Task1: %@",[NSThreadcurrentThread]);
[NSThreadsleepForTimeInterval:3];
// 離開
dispatch_group_leave(group_t2);
});
});
dispatch_group_enter(group_t2);
dispatch_group_async(group_t2, queue_t2, ^{
dispatch_async(queue_t2, ^{
NSLog(@"group_async Task2: %@",[NSThreadcurrentThread]);
[NSThreadsleepForTimeInterval:3];
// 離開
dispatch_group_leave(group_t2);
});
});
dispatch_group_enter(group_t2);
dispatch_group_async(group_t2, queue_t2, ^{
dispatch_async(queue_t2, ^{
NSLog(@"group_async Task3: %@",[NSThreadcurrentThread]);
[NSThreadsleepForTimeInterval:3];
// 離開
dispatch_group_leave(group_t2);
});
});
// 組裡的任務完成後通知
dispatch_group_notify(group_t2, queue_t2_1, ^{
NSLog(@"group_async Task4: %@",[NSThreadcurrentThread]);
[NSThreadsleepForTimeInterval:3];
});
相關推薦
iOS--GCD的常見用法,group、barrier、semaphore
專案中用到了阿里雲上傳,有20張圖片加3個音訊加視訊檔案,用到了GCD的東西,總結了一下。 程式碼地址:https://github.com/SunshineTraveller/LMGCDTEST
QT中圖表類QChart系列之(1)-基本用法,畫折線圖、各個類之間的關係
首先要注意3點: (1)在.pro檔案中新增:QT += charts。 (2)用到QChart的檔案中新增:QT_CHARTS_USE_NAMESPACE,或者:using namespace QtCharts; 在ui介面中拖入一個graphicsVi
Centos7防火牆用法,centos7開放埠、關閉埠
Centos7不再使用iptables而是使用firewall 所以防火牆相關的命令也改了 檢視開放的埠 firewall-cmd --list-ports 開放80埠 firewall-cmd --zone=public --add-port=80/tcp --p
iOS TextField輸入價格,只能輸入數字、小數點且保留兩位
1.只能輸入.0~9,其他字元不可輸入 2.有且只有一個小數點 3.第一個字元為0,第二個必須輸入. 4.第一個字元為. 前面自動加0 5.小數點後面最多隻能輸入兩位 - (BOOL)te
iOS程式生命週期,蘋果內購、微信支付、支付寶支付
開發4年了,很少寫部落格,主要是懶,哈哈。遇到不清晰的就翻翻以前的程式碼。有時還找不到,現在發現部落格可以更方便查詢知識點,所以用部落格做筆記吧。也有助於大家學習、交流,先寫一些基礎的吧。 一、iOS程式常識 1. 生命週期 程式啟動時,載入xi
Golang | 簡介channel常見用法,完成goroutin通訊
今天是golang專題的第14篇文章,大家可以點選上方的專輯回顧之前的內容。 今天我們來看看golang當中另一個很重要的概念——通道。我們之前介紹goroutine的時候曾經提過一個問題,當我們啟動了多個goroutine之後,我們怎麼樣讓goroutine之間保持通訊呢? 要回答這個問題就需要用到通道。
iOS 計時器三種定時器的用法NSTimer、CADisplayLink、GCD
並且 reat clas 就會 固定 tro run mod 不同 原文:http://www.cocoachina.com/ios/20160919/17595.html 一、三種計時器 二、全局倒計時 #import "ViewController.h" @inte
【精】iOS知識樹,知識點(包括物件、Block、訊息轉發、GCD、執行時、runloop、動畫、Push、KVO、tableview,UIViewController、提交AppStore)
本文旨在總結iOS知識網路,知識點,該知識網路羅列出常見UIKit、Foundation的物件特點和一些使用經驗,可以看成是一本書;文字編輯採用樹的形式,對知識點進行羅列,並標註一些使用經驗(★)希望對初學者有用或給一些解決疑難雜症者提供思路;某些知識點會深入
iOS開發中SQLite簡單使用(基礎用法:建立表,增、刪、改、查)
SQLite,是一款輕型的資料庫,是遵守ACID的關係型資料庫管理系統,它包含在一個相對小的C庫中。它是D.RichardHipp建立的公有領域專案。它的設計目標是嵌入式的,而且目前已經在很多嵌入式產
go語言筆記——切片函數常見操作,增刪改查和搜索、排序
通過 學習 strings 完整 官方文檔 二分 func fun 必須 7.6.6 搜索及排序切片和數組 標準庫提供了 sort 包來實現常見的搜索和排序操作。您可以使用 sort 包中的函數 func Ints(a []int) 來實現對 int 類型的切片排序。例如
數組去重,call、apply、bind之間的區別,this用法總結
步驟 -- 之間 undefined 定義 ply clas turn 需要 一、數組去重,直接寫到Array原型鏈上。 1 //該方法只能去除相同的數字 不會去判斷24和‘24‘是不同的 所有數字和字符串數字是相同是重復的 2 Array.prototype
【python學習】今天看看學習 %d ,%s, %f 等用法,下面的學習例子是說輸入名字、年齡、工作,工資。並給出65歲退休還差多久的計算
msg ear end style 資料 科學 一個 保留 value 今天看看學習 %d ,%s, %f 等用法。%d 是占位符整數,%s 是占位符,%f 是浮點數。下面的學習例子是說輸入名字、年齡、工作,工資。並給出65歲退休還差多久的計算。重點在於用占位符來print
常見的 4 種HTML5錯誤用法,你用錯了幾個
特性 tail flow 清晰 per 描述 收藏 語義 了解 一、不要使用section作為div的替代品 人們在標簽使用中最常見到的錯誤之一就是隨意將HTML5的等價於——具體地說,就是直接用作替代品(用於樣式)。在XHTML或者HTML4中,我們常看到這樣
常見的4種HTML5錯誤用法,你用錯了幾個?
常見 投票 都是 其中 conda con 代碼 圖表 簡單 一、不要使用section作為div的替代品 人們在標簽使用中最常見到的錯誤之一就是隨意將HTML5的等價於——具體地說,就是直接用作替代品(用於樣式)。在XHTML或者HTML4中,我們常看到這樣的代碼: Pa
閉包,閉包用途,call、apply、bind 的用法
聲明 func 相互 function span all this 內存 bsp 什麽是閉包:“函數”和“函數內部能訪問到的變量(也叫環境)”的總和,就是一個閉包。JavaScript有兩種作用域:全局作用域和函數作用域。函數內部可以直接讀取全局變量。但是,在函數外部無法讀
hivesql中concat,concat_ws,collect_set 的常見用法
1.concat是將字串連線起來,相當於python中的join; concat_ws(合併時的分隔符,合併id,name........) collect_set(欄位):根據某個欄位分組後,把分在一組的資料合併在一起,預設分隔符',' 2.使用concat_ws()和collect_
iOS 適配 iOS11,會引起呼叫系統相簿、分享郵件的系統介面上移問題
適配 iOS11,避免滾動檢視頂部出現20的空白,全域性設定了UIScrollView。 if (@available(iOS 11.0, *)) { [[UIScrollView appearance] setContentInsetAdjustmentBehavior:UIScrollView
C++中tan、atan、sin、cos等三角函式用法的程式碼演示及結果,注意角度和弧度的轉換!
進行相機座標系相關公式推導時,經常碰到三角函式的使用。時間一長就生疏,碰到問題再查,很費時間。所以就總結一下,也希望能幫到更多的人。下面就通過簡練的程式碼,把常用的cos、sin、tan、atan等通過程式碼及結果都說清楚。注意弧度和角度的區別!!! 1、程式碼 #include <
酷課堂iOS交流群,聚集了一群熱愛技術、有趣、有料,平均Q齡在10年以上的“老司機”,他們遍佈在全國
新書即將上市: 這兩天收到出版社的樣書,預計這兩週將陸續開始上架,感興趣的小夥伴,到時可在天貓、噹噹、京東搜尋“李發展”即可找到。 &nb
酷課堂iOS交流群,聚集了一群熱愛技術、有趣、有料,平均Q齡在10年以上的“老司機”,他們遍布在全國
www. 同步 翻譯 技巧 failed touch 增強現實 -a 你們 新書即將上市: 這兩天收到出版社的樣書,預計這兩周將陸續開始上架,感興趣的小夥伴,到時可在天貓、當當、京東搜索“李發展”即可找到。 ? ? ? ? ? ? ? ? ? ? ? ? ? ? 本書內容簡