国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

GCD

2019-11-14 18:33:17
字體:
來源:轉載
供稿:網友

GCD(中央調度)

Grand Central Dispatch(GCD)包含語言特點、運行庫和系統增強功能,它提供系統的、綜合的改進,進而去支持并發代碼在iOS和OSX多核硬件上的執行。

子系統、CoreFoundation和Cocoa APIs 已經都延伸去使用這些功能,進而幫助系統和你的應用程序運行地更快,更高效,而且提高響應能力。考慮到一個程序有效使用多核的困難性,更不要說在不同的計算機中使用不同數量的計算機內核或者多個應用程序環境中競爭核。CGC,一個在系統層面的操作,可以更好的適應所有運行程序的需要,以平衡的方式去匹配可用系統資源。

這個文檔用來描述GCD 的API,它在Unix系統水平支持異步執行操作。你可以使用這些API來管理與文件描述符、Mach 端口、信號或者計時器的相互作用。在OS Xv10.7以及以后,你也可以使用GCD去處理常規目的的異步I/O操作。

GCD并不限制于系統級別的應用程序,但是在你使用它到更高級別的應用程序中之前,你應該考慮一下Cocoa提供的簡單的函數是不是比GCD更簡單去滿足你程序的需求。

注意

當你在把CGD和fork系統調用混合適用的時候,如果一個進程GCD調用優先于fork調用,這樣就是不安全的。指導成功調用exec或者相關函數之后才安全。

同步與異步

  • 同步請求:同步請求可以從因特網請求數據,一旦發送同步請求,程序將停止用戶交互,直至服務器返回數據完成,才可以進行下一步操作,
  • 異步請求:異步請求不會阻塞主線程,而會建立一個新的線程來操作,用戶發出異步請求后,依然可以對UI進行操作,程序可以繼續運行

使用GCD步驟

  • 創建任務,確定你要進行的操作
  • 將任務 添加到隊列中,GCD會自動將任務從隊列中取出(FIFO),放到相應的線程中執行

兩個主要執行任務函數

  • 異步執行函數(開啟新線程):void dispatch_async ( dispatch_queue_t queue, dispatch_block_t block );
  • 同步執行函數(不開啟新線程):void dispatch_sync ( dispatch_queue_t queue, dispatch_block_t block );

隊列類型

  • 并發隊列:可以讓多個任務并發執行,并發功能只有在異步函數下才有效。
  • 串行隊列:任務一個接著一個執行。

  • 創建并發隊列:
    GCD默認已經提供了全局的并發隊列,功整個應用使用,我們不需要手動創建,只要使用dispatch_get_global_queue函數獲得全局的并發隊列。
  • 創建串行隊列
    串行隊列可以通過以下兩種方式獲得:

    • dispatch_queue_create創建
    • 使用主隊列dispatch_get_main_queue(),朱隊列是GCD自帶的一種特殊的串行隊列,放在主隊列的任務都會在主線程中執行。

GCD對象和自動引用計數

當你使用OC編譯器運行你的app時,所有的dispatch對象都是OC對象。同樣的,當自動引用計數(ARC)允許時,dispatch對象的保持和釋放都是自動的,就像其他OC對象一樣。當ARC不允許時,使用dispatch_retaindispatch_release函數(或者OC語言)去保持和釋放你的dispatch對象。你不能使用Core Foundation retain/release函數去保持和釋放dispatch對象。
在晚一些的的項目構建中,如果你需要在ARC允許的app中使用retain/release語法(為了維護與現有代碼的兼容性),你可以禁用OC dispathc對象通過添加 -DOS_OBJECT_USE_OBJE=0到你的編譯器標示中。

函數
  • dispatch_ get_main_queue
    * 返回與系統主線程相關的串行調度隊列。
    * 聲明
    dispatch_queue_t dispatch_get_main_queue ( void );
    * 返回值
    返回主隊列。這個隊列是為了在調用main之前,為了主線程而自動創建的。
    * 討論
    主線程是系統自動創建的,它和你的應用程序主線程相關聯。你的程序使用下面三個函數中的一個(僅一個)來調用主隊列:
    * 調用dispatch_main
    * 在iOS調用UIapplicationMain或者在OS X調用NSApplicationMain.
    * 在主線程上使用CFRunLooPRef。
    和全局并發隊列一起,調用dispathc_suspend,dispatch_resume,dispatch_set_context,調用這些都是沒有影響的。

例子

主線程上調用異步

- (void)syncOnMainThread{    NSLog(@"task2:%@",[NSThread currentThread]);       dispatch_queue_t queue = dispatch_get_main_queue();        dispatch_async(queue, ^{        NSLog(@"task1:%@",[NSThread currentThread]);    });        NSLog(@"task3:%@",[NSThread currentThread]);}

輸出結果:

死鎖:使用同步函數在主隊列執行,會造成線程死鎖情況

- (void)testDeadLock{    NSLog(@"task2:%@",[NSThread currentThread]);        dispatch_queue_t queue = dispatch_get_main_queue();        dispatch_sync(queue, ^{        NSLog(@"task1:%@",[NSThread currentThread]);    });        NSLog(@"task3:%@",[NSThread currentThread]);}

同步執行串行隊列:不會開啟新線程,按照順序執行

- (void)syncChuanxing{    dispatch_queue_t queue = dispatch_queue_create("gcd.queue", NULL);    //添加任務到隊列中執行任務    dispatch_sync(queue, ^{        NSLog(@"task1:%@",[NSThread currentThread]);    });    dispatch_sync(queue, ^{        NSLog(@"task2:%@",[NSThread currentThread]);    });    dispatch_sync(queue, ^{        NSLog(@"task3:%@",[NSThread currentThread]);    });}

執行結果:

在同步函數中執行并發任務:在主線程中按順序執行,并發隊列失去并發功能

- (void)syncBingfa{    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);    //添加任務到隊列中執行任務    dispatch_sync(queue, ^{        NSLog(@"task1:%@",[NSThread currentThread]);    });    dispatch_sync(queue, ^{        NSLog(@"task2:%@",[NSThread currentThread]);    });    dispatch_sync(queue, ^{        NSLog(@"task3:%@",[NSThread currentThread]);    });   }

執行結果:

異步函數在串行隊列上執行:可見程序開啟單個線程的順序執行

- (void)asynChuanxing{    //獲得全局的并發隊列    dispatch_queue_t queue =dispatch_queue_create("gcd.queue", NULL);//    dispatch_queue_t queue =dispatch_get_main_queue();    //添加任務到隊列中執行任務    dispatch_async(queue, ^{        NSLog(@"task1:%@",[NSThread currentThread]);    });    dispatch_async(queue, ^{        NSLog(@"task2:%@",[NSThread currentThread]);    });    dispatch_async(queue, ^{        NSLog(@"task3:%@",[NSThread currentThread]);    });}

執行結果:

異步函數在并行隊列上執行

- (void)asynBingxing{    //獲得全局的并發隊列    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);    //添加任務到隊列中執行任務    dispatch_async(queue, ^{        NSLog(@"task1:%@",[NSThread currentThread]);    });    dispatch_async(queue, ^{        NSLog(@"task2:%@",[NSThread currentThread]);    });    dispatch_async(queue, ^{        NSLog(@"task3:%@",[NSThread currentThread]);    });}

執行結果:

每次執行的結果可能不一樣

延時執行

- (void)deleayRun{    //通常的延時執行    dispatch_queue_t queue = dispatch_get_main_queue();    dispatch_async(queue, ^{        [self performSelector:@selector(runWith:) withObject:@"2" afterDelay:2.0];    });        //gcd函數執行    dispatch_queue_t queue1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);    dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0*NSEC_PER_SEC));    dispatch_after(when, queue1, ^{        [self runWith:1];    });    //上邊的gcd函數執行和這個一樣    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{        [self runWith:2];    });            }#pragma mark - RunMethod- (void)runWith:(NSInteger)tag{    NSLog(@"執行函數:%ld",(long)tag);}

組隊列

- (void)zuDuiLie{    // 創建一個組    dispatch_group_t group = dispatch_group_create();    // 下載圖片1    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{       NSLog(@"下載圖片1:%@",[NSThread currentThread]);    });    // 下載圖片2    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{        NSLog(@"下載圖片2:%@",[NSThread currentThread]);    });    // group任務都執行完畢,再執行其他操作    dispatch_group_notify(group, dispatch_get_main_queue(), ^{        // 合并圖片        NSLog(@"開始合并圖片:%@",[NSThread currentThread]);    });}

執行結果:

附:

下邊是2015年8月30日上9:50更新的。


1、 線程:1個CPU執行的CPU命令列為一條無分叉的路徑即為一個線程。
2、dispatch_queue_create的作用是創建一個派遣隊列,是串行隊列。
3、dispatch_set_target_queue:變更生成的Dispatch_Queue的執行優先級要使用dispatch_set_target_queue函數。它有兩個參數,第一個參數是指定要變更執行優先級的Dispatch Queue;第二個參數是指定要使用的執行優先級相同優先級的Global Dispatch Queue為第二個參數。
4、dispatch_after:延遲執行
5、dispatch_group_notify:是把多個處理全部結束后再執行結束處理。最后可以用dispatch_group_notify(group名稱)執行結束處理。
6、dispatch_group_wait:等待全部處理執行結束。
7、dispatch_barrier_async:會等待追加到并發派遣隊列上的并行執行的處理全部結束之后,再將制定的函數處理追加到并發派遣隊列。(有點類似于addDepency)先處理前面的幾個操作,然后遇到barrier后只執行1個barrier追加的處理,然后再繼續執行后面的處理。
8、dispatch_apply:該函數按照指定的次序將指定的Block追加到指定的Dispatch Queue中,并等待全部處理執行結束。
9、dispatch_suspend/dispatch_resume:用于有時候不希望執行以追加的處理。
10、dispatch_once:保證在應用程序執行中只執行一次指定處理。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 仙居县| 仁布县| 苗栗市| 西藏| 徐闻县| 满城县| 天镇县| 疏附县| 田东县| 英德市| 呼图壁县| 右玉县| 南木林县| 汪清县| 安化县| 兰溪市| 交城县| 湖口县| 镇远县| 宜州市| 宁陕县| 广丰县| 秭归县| 逊克县| 弥勒县| 西乌珠穆沁旗| 墨玉县| 子长县| 依兰县| 五大连池市| 连云港市| 永登县| 东乌| 昭苏县| 双牌县| 正阳县| 安多县| 休宁县| 乡城县| 娄烦县| 新建县|