IOS多線程開發之GCD

來源:互聯網
上載者:User

標籤:gcd   多線程   

概要

       GCD的全稱是Grand Central Dispatch(譯為中心調度隊列?),可以理解為線程管理隊列,是蘋果公司為多核的並行運算提出的解決方案,能夠根據系統內容自適應線程管理,基本屬於全自動的線程管理。

       在GCD裡面,任務需要放到隊列裡面執行,隊列根據自身屬性分發任務執行,不過原則總是FIFO。隊列分為串列和並行隊列,串列隊列是隊列裡面只有一個線程,所以隊列裡面只有一個任務在執行,而並行則會根據系統內容,自動調節線程數,可支援同時多個任務執行。

       GCD提供了建立以及擷取隊列的方法,包括擷取全域並發隊列、串列主線程隊列以及建立自己的串列隊列(為什麼沒有建立並發的?個人理解是需要建立並發的和直接使用全域並發的效果一樣)。串列隊列因為同時只能執行一個任務的特點,所以可以滿足某些需要按順序執行任務的工作,用以充當鎖、保護共用資源和資料。


串列隊列
  • 主線程隊列
    擷取主線程隊列,住主隊列是GCD內建的一種串列隊列,該主隊列的任務會在主線程上執行。
    // 擷取串列的主線程隊列dispatch_queue_t queue = dispatch_get_main_queue();// 非同步執行任務dispatch_async(queue, ^{            NSLog(@"async-%@");        });// 同步執行任務dispatch_sync(queue, ^{            NSLog(@"sync-%@");          });

  • 自訂隊列
    // 建立隊列,指定名稱,屬性設為預設即可dispatch_queue_t queue = dispatch_queue_create("my_serial_queue", NULL);// 新增工作到隊列// 如果不是ARC的話,釋放該隊列dispatch_release(queue);
並發隊列

 GCD提供的全域並發隊列,供整個應用使用,不需要自己再去建立

GCD提供的全域並發隊列,供整個應用使用,不需要自己再去建立// 擷取全域並發隊列,可以選擇優先順序// #define DISPATCH_QUEUE_PRIORITY_HIGH         2// #define DISPATCH_QUEUE_PRIORITY_DEFAULT      0// #define DISPATCH_QUEUE_PRIORITY_LOW          (-2)// #define DISPATCH_QUEUE_PRIORITY_BACKGROUND   INT16_MINdispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);// 同步執行block任務dispatch_async(queue, ^{        NSLog(@"sync-%@");    });// 非同步執行block任務dispatch_async(queue, ^{        NSLog(@"async-%@");    });// 非同步執行方法任務dispatch_async_f(queue, queue_f);

主要函數列表
// 同步執行任務blockdispatch_sync(dispatch_queue_t queue, dispatch_block_t block);// 以非同步方式執行任務blockdispatch_async(dispatch_queue_t queue, dispatch_block_t block);// 非同步執行程式定義的方法void dispatch_async_f ( dispatch_queue_t queue, void *context, dispatch_function_t work );// 建立串列線程隊列dispatch_queue_t  dispatch_queue_create(const char *label,  dispatch_queue_attr_t attr);// 手動釋放隊列void dispatch_release ( dispatch_object_t object );// 擷取串列主線程隊列dispatch_queue_t dispatch_get_main_queue ( void );// 擷取全域並發隊列dispatch_queue_t dispatch_get_global_queue ( long identifier, unsigned long flags );// 擷取當前代碼的調度隊列dispatch_queue_t dispatch_get_current_queue ( void );// 延遲非同步執行block,對應的有函數dispatch_after_fvoid dispatch_after ( dispatch_time_t when, dispatch_queue_t queue, dispatch_block_t block );// 建立一個隊列組dispatch_group_t dispatch_group_create ( void );

程式碼範例
  • 自訂串列隊列
    - (void)viewDidLoad{    [super viewDidLoad];        // 主線程    NSLog(@"main-%@",[NSThread currentThread]);        // 建立串列線程隊列    dispatch_queue_t queue = dispatch_queue_create("my_serial", 0);        // 非同步執行任務    dispatch_async(queue, ^{        NSLog(@"async1-%@", [NSThread currentThread]);    });    // 同步執行任務    dispatch_sync(queue, ^{        NSLog(@"sync-%@", [NSThread currentThread]);    });    // 非同步執行任務    dispatch_async(queue, ^{        NSLog(@"async2-%@", [NSThread currentThread]);    });}
    輸出結果
    2015-01-01 15:00:35.213 GCDDemo[10763:14132221] main-<NSThread: 0x7fe192e158c0>{number = 1, name = main}2015-01-01 15:00:35.214 GCDDemo[10763:14132356] async1-<NSThread: 0x7fe192d0b5d0>{number = 2, name = (null)}2015-01-01 15:00:35.214 GCDDemo[10763:14132221] sync-<NSThread: 0x7fe192e158c0>{number = 1, name = main}2015-01-01 15:00:35.214 GCDDemo[10763:14132356] async2-<NSThread: 0x7fe192d0b5d0>{number = 2, name = (null)}
    因為是串列任務隊列,所以隊列只有一個線程,因此兩個非同步任務擷取的線程資訊一樣其number都是1,而同步任務因為在主線程執行,所以擷取的線程資訊和主線程資訊一樣。此外,因為sync在async2之前,所以asyn要等到syn執行完畢。

  • 主線程隊列
    - (void)viewDidLoad{    [super viewDidLoad];        // 主線程    NSLog(@"main-%@",[NSThread currentThread]);        // 建立串列線程隊列,因為主線程隊列需要在其他線程使用    dispatch_queue_t queue = dispatch_queue_create("my_serial", 0);        // 非同步執行任務    dispatch_async(queue, ^{                // 擷取主線程隊列        dispatch_queue_t queue = dispatch_get_main_queue();                // 同步執行任務        dispatch_sync(queue, ^{            NSLog(@"sync-%@", [NSThread currentThread]);        });        // 非同步執行任務        dispatch_async(queue, ^{            NSLog(@"async-%@", [NSThread currentThread]);        });    });}
    輸出結果
    2015-01-01 15:29:35.856 GCDDemo[10800:14143728] main-<NSThread: 0x7ff7d9f0e920>{number = 1, name = main}2015-01-01 15:29:35.898 GCDDemo[10800:14143728] sync-<NSThread: 0x7ff7d9f0e920>{number = 1, name = main}2015-01-01 15:29:35.900 GCDDemo[10800:14143728] async-<NSThread: 0x7ff7d9f0e920>{number = 1, name = main}
    從直接結果可以看到擷取的線程資訊都一樣,都是主線程資訊,因為這些代碼都是在主線程裡面執行的。

  • 全域隊列
    - (void)viewDidLoad{    [super viewDidLoad];        // 主線程    NSLog(@"main-%@",[NSThread currentThread]);        // 建立串列線程隊列,因為主線程隊列需要在其他線程使用    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);        // 非同步執行任務    dispatch_async(queue, ^{        NSLog(@"async1-started, %@", [NSThread currentThread]);        sleep(arc4random()%10);        NSLog(@"async1-finished, %@", [NSThread currentThread]);        });        // 非同步執行任務    dispatch_async(queue, ^{        NSLog(@"async2-started, %@", [NSThread currentThread]);        sleep(arc4random()%10);        NSLog(@"async2-finished, %@", [NSThread currentThread]);    });            // 非同步執行任務    dispatch_async(queue, ^{        NSLog(@"async3-started, %@", [NSThread currentThread]);        sleep(arc4random()%10);        NSLog(@"async3-finished, %@", [NSThread currentThread]);    });        // 非同步執行任務    dispatch_sync(queue, ^{        NSLog(@"sync-started, %@", [NSThread currentThread]);        sleep(arc4random()%10);        NSLog(@"sync-finished, %@", [NSThread currentThread]);    });}
    輸出結果
    2015-01-01 15:41:11.802 GCDDemo[10851:14149580] main-<NSThread: 0x7f9cda427820>{number = 1, name = main}2015-01-01 15:41:11.803 GCDDemo[10851:14149580] sync-started, <NSThread: 0x7f9cda427820>{number = 1, name = main}2015-01-01 15:41:11.803 GCDDemo[10851:14149677] async3-started, <NSThread: 0x7f9cda624920>{number = 3, name = (null)}2015-01-01 15:41:11.803 GCDDemo[10851:14149679] async2-started, <NSThread: 0x7f9cda4300c0>{number = 2, name = (null)}2015-01-01 15:41:11.804 GCDDemo[10851:14149680] async1-started, <NSThread: 0x7f9cda608e80>{number = 4, name = (null)}2015-01-01 15:41:12.809 GCDDemo[10851:14149680] async1-finished, <NSThread: 0x7f9cda608e80>{number = 4, name = (null)}2015-01-01 15:41:13.808 GCDDemo[10851:14149679] async2-finished, <NSThread: 0x7f9cda4300c0>{number = 2, name = (null)}2015-01-01 15:41:14.805 GCDDemo[10851:14149580] sync-finished, <NSThread: 0x7f9cda427820>{number = 1, name = main}
    從執行結果可以三個非同步部分的代碼的nunber都不一樣,而且這些都同時執行,說明在不同的線程同時執行,而同步的線程資訊和主線程資訊相同。

IOS多線程開發之GCD

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.