美文网首页
多线程-GCD

多线程-GCD

作者: c_xiaoqiang | 来源:发表于2015-06-30 16:20 被阅读86次

Dispatch Queues

  • Serial Dispatch Queue
    单线程模式,一个任务处理完才会执行下一个任务
  • Concurrent Dispatch Queue
    多线程处理,不等待前一个线程结束就会开始执行下一个线程

Obtaining Dispatch Queues

有两种方式可以创建Dispatch Queues:dispatch_queue_createmain dispatch queue / global dispatch queue

dispatch_queue_create

dispatch_queue_t serialQueue = dispatch_queue_create("mySerialQueue", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t concurrentQueue = dispatch_queue_create("myConcurrent", DISPATCH_QUEUE_CONCURRENT);

dispatch_async(serialQueue, ^{
    NSLog(@"Hello 1");
});
dispatch_async(serialQueue, ^{
    NSLog(@"Hello 2");
});
dispatch_async(serialQueue, ^{
    NSLog(@"Hello 3");
});
dispatch_async(concurrentQueue, ^{
    NSLog(@"Hello 4");
});
dispatch_async(concurrentQueue, ^{
    NSLog(@"Hello 5");
});

Main Dispatch Queue/Global Dispatch Queue

这两个方法是用来获得系统提供的Dispatch Queue。main dispatch queue是系统的主线程,主线程是Serial dispatch queue。而Global Dispatch Queue是Concurrent dispatch queue。Global Dispatch Queue有优先级的设置

dispatch_queue_t globalHighQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_queue_t globalDefaultQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_queue_t globalLowQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
dispatch_queue_t globalBackGroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
dispatch_async(globalHighQueue, ^{
    NSLog(@"high");    
});

dispatch_async(globalDefaultQueue, ^{
    NSLog(@"default");
});

dispatch_async(globalLowQueue, ^{
    NSLog(@"low");
    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"main");
    });
});

dispatch_async(globalBackGroundQueue, ^{
    NSLog(@"back");
});

Controlling Dispatch Queues(GCD API使用)

dispatch_set_target_queue

该方法用来变更一个创建好的dispatch queue的优先级,当一个dispatch queue由dispatch_queue_create()创建时,他们默认为default priority。如果要更改就可以使用该方法

dispatch_queue_t globalQueue = dispatch_queue_create("test target", NULL);
dispatch_set_target_queue(globalQueue, globalHighQueue);

dispatch_after

该方法用来在queue里面设定开始任务的时间

dispatch_async(globalHighQueue, ^{
    NSLog(@"high");
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"high main");
    });     
});

Dispatch Group

全部任务结束的时候,可能需要做一些处理,利用group可以实现这个功能。

dispatch_group_t group = dispatch_group_create();//创建
dispatch_group_async(group, globalHighQueue, ^{  //添加
    NSLog(@"high 1");
});
dispatch_group_async(group, globalHighQueue, ^{
    NSLog(@"high 2");
});
dispatch_group_async(group, globalHighQueue, ^{
    NSLog(@"high 3");
});

dispatch_group_notify(group,dispatch_get_main_queue(), ^{
    NSLog(@"high end");
});
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);//等待group运行结束

dispatch_barrier_async

用来设置该任务完成之前完全占有线程,比如用来处理读写冲突,当写的时候,读线程必须等待。(对于DISPATCH_QUEUE_CONCURRENT来说)

dispatch_async(concurrentQueue, ^{
    NSLog(@"read 1");
});
dispatch_async(concurrentQueue, ^{
    NSLog(@"read 2");
});
dispatch_barrier_async(concurrentQueue, ^{
    NSLog(@"writing");
});
dispatch_async(concurrentQueue, ^{
    NSLog(@"read 3");
});

dispatch_once

只执行一次的API。

static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    NSLog(@"once");
});

dispatch_suspend/dispatch_resume

挂起和恢复

dispatch_suspend(queue);
dispatch_resume(queue);

dispatch_sync

dispatch_async是异步添加block不会阻塞线程,而dispatch_sync是同步的会阻塞线程的运行,如果当前线程和要处理的block线程相同,就会产生死锁。两者从功能上是差不多的。

dispatch_async(concurrentQueue, ^{
    NSLog(@"read 1");
    dispatch_sync(concurrentQueue, ^{
        NSLog(@"线程阻塞--死锁");
    });
});

dispatch_apply

dispatch_apply与dispatch_sync函数和Dispatch Group相关联,该函数按照指定的次数将block追加到Dispatch Group中,并等待执行结束后返回。

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_apply(10, queue, ^(size_t index) {
NSLog(@"%zu", index); });
NSLog(@"done");

参考书籍

《Pro Multithreading and Memory Management for iOS and OS X》

相关文章

网友评论

      本文标题:多线程-GCD

      本文链接:https://www.haomeiwen.com/subject/jeoeqttx.html