OC底层->多线程

654 阅读2分钟

ios中的常见多线程方案

image.png

GCD的常用函数

  • GCD中有2个用来执行任务的函数
    • 用同步的方式执行任务

    • dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);

      • queue:队列
      • block:任务
    • 用异步的方式执行任务

    • dispatch_async(dispatch_queue_t queue, dispatch_block_t block);

    • GCD源码:github.com/apple/swift…

GCD的队列

  • GCD的队列可以分为2大类型
    • 并发队列(Concurrent Dispatch Queue)

      • 可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务),并不是真的同时执行,只是在多个任务之前切换执行,一会执行a,一会执行b.
      • 并发功能只有在异步(dispatch_async)函数下才有效
    • 串行队列(Serial Dispatch Queue)

      • 让任务一个接着一个地执行(一个任务执行完毕后,再执行下一个任务)

容易混淆的术语

  • 有4个术语比较容易混淆:同步、异步、并发、串行
    • 同步和异步主要影响:能不能开启新的线程

      • 同步:在当前线程中执行任务,不具备开启新线程的能力
      • 异步:在新的线程中执行任务,具备开启新线程的能力
    • 并发和串行主要影响:任务的执行方式

      • 并发:多个任务并发(同时)执行
      • 串行:一个任务执行完毕后,再执行下一个任务

各种队列的执行效果

image.png

  • 在串行队列中(不会开启新线程),在一个任务中不要同步加入新的任务,这样会产生死锁。
  • 使用sync函数往当前串行队列中添加任务,会卡住当前的串行队列(产生死锁)

// dispatch_sync和dispatch_async用来控制是否要开启新的线程
/** 队列的类型,决定了任务的执行方式(并发、串行)
1.并发队列
2.串行队列
3.主队列(也是一个串行队列)
*/

队列组的使用

  • 思考:如何用gcd实现以下功能
    • 异步并发执行任务1、任务2
    • 等任务1、任务2都执行完毕后,再回到主线程执行任务3 image.png
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    // 创建队列组
    dispatch_group_t group = dispatch_group_create();
    // 创建并发队列
    dispatch_queue_t queue = dispatch_queue_create("my_queue", DISPATCH_QUEUE_CONCURRENT);
    
    // 添加异步任务
    dispatch_group_async(group, queue, ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"任务1-%@", [NSThread currentThread]);
        }
    });
    
    dispatch_group_async(group, queue, ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"任务2-%@", [NSThread currentThread]);
        }
    });
    
    // 等前面的任务执行完毕后,会自动执行这个任务
//    dispatch_group_notify(group, queue, ^{
//        dispatch_async(dispatch_get_main_queue(), ^{
//            for (int i = 0; i < 5; i++) {
//                NSLog(@"任务3-%@", [NSThread currentThread]);
//            }
//        });
//    });
    
//    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
//        for (int i = 0; i < 5; i++) {
//            NSLog(@"任务3-%@", [NSThread currentThread]);
//        }
//    });
    
    dispatch_group_notify(group, queue, ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"任务3-%@", [NSThread currentThread]);
        }
    });
    
    dispatch_group_notify(group, queue, ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"任务4-%@", [NSThread currentThread]);
        }
    });
    
    
}