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

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

iOS多線程-02-GCD

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

簡介


  • GCD(Grand Center Dispatch)是Apple為多核的并行運算提出的解決方案,純C語言
  • 更加適配多核處理器,且自動管理線程的生命周期,使用起來較為方便
  • GCD通過任務和隊列實現多線程功能

    • 任務:描述所要執行的操作
    • 隊列:用來存放所要執行的任務,隊列中的任務遵循FIFO(First In First Out)原則

GCD的任務函數(是否開啟新的線程)


  • 同步

    • 不具備開啟新的線程的能力
    • 同步執行任務的函數

      • void dispatch_sync(dispatch_queue_t queue, dispatch_block_t block),Block類型

        • queue:任務隊列
        • block(代碼塊):所執行的任務
      • void dispatch_sync_f(dispatch_queue_t queue, void *context, dispatch_function_t work),函數類型(每個Block類型都對應一個函數類型)

        • queue:任務隊列
        • context:傳遞給任務函數的參數
        • work(函數):所執行的任務
    • 同步執行任務的其他函數(barrier),在前面的任務執行完畢它才執行,它后邊的任務等它執行完畢才執行

      • void dispatch_barrier_sync(dispatch_queue_t queue, dispatch_block_t block),block類型

        • queue:任務隊列,僅當該參數為并發隊列時,該函數才有意義
      • dispatch_barrier_sync_f(dispatch_queue_t queue, void *context, dispatch_function_t work),函數類型

  • 異步

    • 具備開啟新的線程的能力(需要將任務添加到并發隊列中)
    • 異步執行任務的函數(參數意義與同步函數相同)

      • void dispatch_async(dispatch_queue_t queue, dispatch_block_t block)
      • void dispatch_async_f(dispatch_queue_t queue, void *context, dispatch_function_t work)
    • 異步執行任務的其他函數(barrier),在前面的任務執行完畢它才執行,它后邊的任務等它執行完畢才執行(參數意義與同步函數相同)

      • void dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block)
      • void dispatch_barrier_async_f(dispatch_queue_t queue, void *context, dispatch_function_t work)

GCD的隊列(任務的執行方式)


  • 并發隊列

    • 開啟多個線程,使隊列中的多個任務并發執行(需要異步執行函數的配合)
  • 串行隊列

    • 隊列中的任務一個接一個順序地執行
  • 隊列的種類

    • 串行隊列

      • dispatch_queue_t dispatch_queue_create(const char *label, dispatch_queue_attr_t attr)

        • label:通常為0
        • attr:隊列類型,DISPATCH_QUEUE_SERIAL
    • 并發隊列

      • dispatch_queue_t dispatch_queue_create(const char *label, dispatch_queue_attr_t attr)

        • label:通常為0
        • attr:隊列類型 DISPATCH_QUEUE_CONCURRENT
    • 主隊列(串行,只能在主線程中運行)

      • dispatch_queue_t dispatch_get_main_queue(void),獲取主隊列
    • 全局隊列(并發)

      • dispatch_queue_t dispatch_get_global_queue(long identifier, unsigned long flags)

任務與隊列的組合


  • 同步函數

    • 同步函數主隊列

      /**- 運行在主線程主隊列(未開啟新的線程),主線程被卡死- 原因:任務代碼等待著當前函數執行完畢才能執行(當前函數正在執行且未執行完畢);	   當前函數等待著任務代碼 執行完畢才能執行(當前任務正在執行且未執行完畢);	   相互等待,出現死鎖*///獲取主隊列dispatch_queue_t queue = dispatch_get_main_queue();//添加任務到隊列dispatch_sync(queue, ^{    //任務1代碼});dispatch_sync(queue, ^{    //任務2代碼});
    • 同步函數串行隊列

      /**- 運行在主線程串行非主隊列(未開啟新的線程),任務串行執行*///創建串行隊列dispatch_queue_t queue = dispatch_queue_create("com.23565@QQ", DISPATCH_QUEUE_SERIAL);//添加任務到隊列dispatch_sync(queue, ^{    //任務1代碼});dispatch_sync(queue, ^{    //任務2代碼});
    • 同步函數并發隊列

      /**- 運行在非主線程并發隊列(未開啟新的線程),任務串行執行*///獲取全局隊列(并發)dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);//將任務加至隊列dispatch_sync(queue, ^{    //任務1代碼});dispatch_sync(queue, ^{    //任務2代碼});
  • 異步函數

    • 異步函數主隊列

      /**- 運行在主線程主隊列(未開啟新的線程),任務串行執行*/// 獲得主隊列dispatch_queue_t queue = dispatch_get_main_queue();// 將任務加入隊列dispatch_async(queue, ^{    //任務1代碼});dispatch_async(queue, ^{    //任務2代碼});
    • 異步函數串行隊列

      /**- 運行在主函數串行非主隊列(未開啟新的線程),任務串行執行*///創建串行隊列dispatch_queue_t queue = dispatch_queue_create("com.23565@qq", DISPATCH_QUEUE_SERIAL);//將任務加至隊列dispatch_async(queue, ^{    //任務1代碼})dispatch_async(queue, ^{    //任務2代碼})
    • 異步函數并發隊列

      /**- 運行在非主線程并發隊列(開啟新的線程),任務并發執行- 系統根據任務創建線程(無法確定任務執行在哪個線程)*///獲得全局并發隊列dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);//將任務加入隊列dispatch_async(queue, ^{    //任務1代碼});dispatch_async(queue, ^{    //任務2代碼});

      線程之間的通信


  • 從主線程到子線程

    • 注意

      • 只有異步函數與并發隊列的組合,才會開啟新的線程,使任務并發執行
      • 通常使用異步函數將任務添加到并發隊列中,來實現從主線程到子線程的通信
    • 實現代碼

      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{		//需要在子線程中執行的任務代碼	})
  • 從子線程到主線程

    • 注意

      • 主隊列中的任務只能在主線程中執行
      • 通常使用異步/同步函數將任務添加到主隊列中,來實現從子線程到主線程的通信
    • 實現代碼

      dispatch_async(dispatch_get_main_queue(), ^{        //需要在主線程中執行的代碼    })

GCD的其他任務


  • 單次執行(通常用在單例模式的設計中)

    //定義一個標記static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{    //此處的代碼只會被執行一次});
  • 延遲執行

    /**- 方法一(GCD)*/dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{    //此處的代碼將延遲執行});/**- 方法二(performSelector)*/[self performSelector:@selector(run) withObject:self afterDelay:2.0];/**- 方法三(NSTimer)*/[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:NO]
  • 快速迭代

    void dispatch_apply(size_t iterations, dispatch_queue_t queue, void (^block)(size_t))/**	iterations:迭代執行的次數	queue:任務隊列	block:迭代執行的代碼	size_t:用來定義當前迭代到第幾次,需要自己添加,如在size_t后添加index索引,記錄當前的迭代次數*/
  • Barrier

    /**- Barrier中的任務,只能在它前面的任務執行完畢才能執行  Barrier后的任務,只能等到它執行完畢才能執行- 要將隊列添加到自己創建的并發隊列中,否其功能等同于函數  void dispatch_async(dispatch_queue_t queue, dispatch_block_t block)*///創建隊列(通常是自己創建的并發隊列)dispatch_queue_t queue = dispatch_queue_create("123", DISPATCH_QUEUE_CONCURRENT);//將任務添加到隊列dispatch_async(queue, ^{    //在Barrier前執行的任務代碼});dispatch_barrier_async(queue, ^{   //Barrier中的任務代碼});dispatch_async(queue, ^{    //在Barrier后執行的任務代碼});
  • 隊列組

    //獲取全局并發隊列dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);//創建隊列組dispatch_group_t group = dispatch_group_create();//添加任務到隊列組dispatch_group_async(group, queue, ^{    	//任務1代碼	});dispatch_group_async(group, queue, ^{    	//任務2代碼	});dispatch_group_notify(group, queue, ^{    	//任務3代碼    	/**    	group組中的所有任務執行完畢在執行    	若group為空,則立即執行    	*/});

GCD定時器


  • 實現原理

    • 創建一個DISPATCH_SOURCE_TYPE_TIMER類型的dispatch source,并添加到dispatch queue,通過dispatch source來響應事件
    • 通過函數void dispatch_source_set_timer(dispatch_source_t source, dispatch_time_t start, uint64_t interval, uint64_t leeway),來設置dispatch source的執行事件
  • 實現代碼

    //獲得隊列dispatch_queue_t queue = dispatch_get_main_queue();//創建一個定時器self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);//設置定時器的各種屬性(起止時間)dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(8.0 * NSEC_PER_SEC));uint64_t interval = (uint64_t)(1.0 * NSEC_PER_SEC);//設置dispatch_source_set_timer(self.timer, start, interval, 0);//設置回調dispatch_source_set_event_handler(self.timer, ^{    //定時器被觸發時所要執行的代碼});//開啟定時器dispatch_resume(self.timer);//取消定時器dispatch_cancel(self.timer);

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 江都市| 金沙县| 乾安县| 梓潼县| 滦南县| 新竹市| 东源县| 长沙县| 忻城县| 错那县| 鹤壁市| 长子县| 抚远县| 邯郸县| 来宾市| 天祝| 垣曲县| 东乌珠穆沁旗| 贵溪市| 达尔| 光泽县| 湘潭市| 浮山县| 潼南县| 昆山市| 上饶县| 渝北区| 长治市| 泊头市| 星子县| 温州市| 滨州市| 炎陵县| 庄河市| 屯门区| 罗定市| 杭锦旗| 思南县| 科技| 唐海县| 沧源|