1. 程式人生 > >iOS--GCD的常見用法,group、barrier、semaphore

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);

非同步組函式裡面的queue不能是序列佇列型別(DISPATCH_QUEUE_SERIAL),否則不會執行,需為併發或者全域性佇列

         3.1.1 特點:group組會在放入group的佇列裡執行的任務會在全部任務執行完畢後通過dispatch_group_notify回撥,告知外界group裡的任務已經全部執行完畢,然後才會執行其他任務,group的佇列會根據任務數建立對應的執行緒數,n個任務就會有n個執行緒,並且是按順序執行的

         3.2  group裡執行的是非同步任務(async)

!此時需要注意了,若為非同步任務,若不做任何處理,所有任務的執行和通知會同時執行,需要新增

enter leave!這樣才能達到group裡的任務都執行完畢才會通知,然後執行其他任務

四、 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 傳送訊號來增加訊號量總數,一旦訊號量總數大於0wait函式就會結束等待,後面的任務就會開始執行

 //////////////////////////////////////////////////////////////


/**

 * 同步序列和佇列數無關,不會開啟新執行緒,會阻塞當前執行緒

 * 本次測試在主執行緒中

 */

- (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中執行的是非同步任務,需要引入entreleave */

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常見用法groupbarriersemaphore

專案中用到了阿里雲上傳,有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 計時器三種定時器的用法NSTimerCADisplayLinkGCD

並且 reat clas 就會 固定 tro run mod 不同 原文:http://www.cocoachina.com/ios/20160919/17595.html 一、三種計時器 二、全局倒計時 #import "ViewController.h" @inte

【精】iOS知識樹知識點(包括物件Block訊息轉發GCD執行時runloop動畫PushKVOtableviewUIViewController提交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 類型的切片排序。例如

數組去重callapplybind之間的區別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

閉包閉包用途callapplybind 的用法

聲明 func 相互 function span all this 內存 bsp 什麽是閉包:“函數”和“函數內部能訪問到的變量(也叫環境)”的總和,就是一個閉包。JavaScript有兩種作用域:全局作用域和函數作用域。函數內部可以直接讀取全局變量。但是,在函數外部無法讀

hivesql中concatconcat_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++中tanatansincos等三角函式用法的程式碼演示及結果注意角度和弧度的轉換!

進行相機座標系相關公式推導時,經常碰到三角函式的使用。時間一長就生疏,碰到問題再查,很費時間。所以就總結一下,也希望能幫到更多的人。下面就通過簡練的程式碼,把常用的cos、sin、tan、atan等通過程式碼及結果都說清楚。注意弧度和角度的區別!!! 1、程式碼 #include <

酷課堂iOS交流群聚集了一群熱愛技術有趣有料平均Q齡在10年以上的“老司機”他們遍佈在全國

新書即將上市: 這兩天收到出版社的樣書,預計這兩週將陸續開始上架,感興趣的小夥伴,到時可在天貓、噹噹、京東搜尋“李發展”即可找到。                         &nb

酷課堂iOS交流群聚集了一群熱愛技術有趣有料平均Q齡在10年以上的“老司機”他們遍布在全國

www. 同步 翻譯 技巧 failed touch 增強現實 -a 你們 新書即將上市: 這兩天收到出版社的樣書,預計這兩周將陸續開始上架,感興趣的小夥伴,到時可在天貓、當當、京東搜索“李發展”即可找到。 ? ? ? ? ? ? ? ? ? ? ? ? ? ? 本書內容簡