美文网首页
GCD任务、队列、线程看我就够了

GCD任务、队列、线程看我就够了

作者: timtory | 来源:发表于2022-03-08 17:02 被阅读0次

GCD开源地址

概念理解

  • 任务: 耗时操作-被执行的代码块
  • 队列:只允许在一端插入数据操作,在另一端进行删除数据操作的特殊线性表;进行插入操作的
    一端称为队尾(入队列),进行删除操作的一端称为队头(出队列);队列具有先进先出(FIFO)的特性。
  • 多线程:多线程的并发是用时间片轮转方法实现的,线程创建、销毁、上下文切换等会消耗CPU性能
  • 多核:是指在一枚处理器(processor)中集成两个或多个完整的计算引擎资源
  • 多核CPU:就是基板上集成有多个单核CPU、核属于cpu的一部分
  • 计算机位数:表示不同的平台下的CPU对内存空间的寻址能力

需要特别理解的操作:

1、code->start:任务开始执行的影响因素
2、线程对任务执行的影响
3、任务执行完成的影响

注意:同步任务在同一线程内嵌套加入同一串行队列 会造成死锁;原因:2任务的执行条件是1任务完成、1任务的完成条件是2任务完成

特点

1、任务是否完成阻塞任务所在线程
2、任务是否完成阻塞入队列
3、任务是否完成阻塞队列内后续任务执行
4、加入队列后立即执行-可同时存在多个相同类型任务执行
5、创建线程
6、等待现有异步任务创建的线程闲置
7、使用任务所在线程执行任务
8、任务开始顺序-先进先开始-fifo(任务执行-代码出队列)

串行队列 并发队列
是否允许创建线程 异步任务允许创建1个异步线程
同一时间最大活跃线程个数 1 32/64等
任务开始顺序 8、 8、
同步任务 1、3、7、 1、4、7、
异步任务 3、5、|6、 4、|5、|6、
通过以上对比可以看到同类任务在串行、并发队列中表现的不同点就是3、4

Let The Code Say

- (dispatch_queue_t)main_queue{//主队列
    return dispatch_get_main_queue();
}
- (dispatch_queue_t)globel_queue{//全局并发队列
    return dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
}
- (dispatch_queue_t)con_queue:(const char *_Nullable)label{//并发队列
    return dispatch_queue_create(label, DISPATCH_QUEUE_CONCURRENT);
}
- (dispatch_queue_t)ser_queue{//串行队列
    return dispatch_queue_create("com.serQueue", DISPATCH_QUEUE_SERIAL);
}
- (void)queueTest {
    dispatch_queue_t con_queue = [self con_queue:"com.conQueue1"];
    dispatch_queue_t con_queue1 = [self con_queue:"com.conQueue2"];
    dispatch_queue_t ser_queue = [self ser_queue];
    dispatch_queue_t globel_queue = [self globel_queue];
    dispatch_queue_t main_queue = [self main_queue];
  // con_queue和globel_queue在作者mac上最大并发是64 猜测最大线程数取决于计算机位数
    for (int i =0; i< 100; i++) {
        dispatch_async(con_queue, ^{
            NSLog(@"dispatch_async_con_queue:%d--- %@",i,[NSThread currentThread]);
            sleep(500);
        });
    }
    // 其他线程给主线程通信
    - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
  // 线程间通信
    - (void)performSelector:(SEL)aSelector onThread:(NSThread *)thread withObject:(id)arg waitUntilDone:(BOOL)wait;

    // 串行队列同一时间只会有一个线程处于活跃 同步任务不会开启新的线程 异步任务会开启一个新的线程 (队列无任务时开始销毁线程)任务结束后大概7秒线程销毁
    dispatch_async(ser_queue, ^{
        NSLog(@"ser_queue1:%@", [NSThread currentThread]);
    });
    dispatch_sync(ser_queue, ^{
        NSLog(@"ser_queue2:%@", [NSThread currentThread]);
    });
    dispatch_async(ser_queue, ^{
        NSLog(@"ser_queue3:%@", [NSThread currentThread]);
    });
    dispatch_sync(ser_queue, ^{
        NSLog(@"ser_queue4:%@", [NSThread currentThread]);
    });
    sleep(7);
    dispatch_async(ser_queue, ^{
        NSLog(@"ser_queue6:%@", [NSThread currentThread]);
    });
  /*
ser_queue1:<NSThread: 0x600000de2000>{number = 6, name = (null)}
ser_queue2:<NSThread: 0x600000dd8340>{number = 1, name = main}
ser_queue3:<NSThread: 0x600000de2000>{number = 6, name = (null)}
ser_queue4:<NSThread: 0x600000dd8340>{number = 1, name = main}
ser_queue6:<NSThread: 0x600000de2000>{number = 4, name = (null)}
*/
    // 验证同步任务立即执行的特点
    dispatch_async(con_queue, ^{
        dispatch_sync(ser_queue, ^{
            NSLog(@"----1:%@", [NSThread currentThread]);
            sleep(10);
            NSLog(@"====1:%@", [NSThread currentThread]);
        });
    });
    dispatch_async(con_queue, ^{
        dispatch_async(ser_queue, ^{
            NSLog(@"----2:%@", [NSThread currentThread]);
            sleep(10);
            NSLog(@"====2:%@", [NSThread currentThread]);
        });
        NSLog(@"2:%@", [NSThread currentThread]);
    });
    dispatch_async(con_queue, ^{
        dispatch_sync(ser_queue, ^{
            NSLog(@"----3:%@", [NSThread currentThread]);
            sleep(10);
            NSLog(@"====3:%@", [NSThread currentThread]);
        });
    });
/*ser_queue
----1:<NSThread: 0x600000801a00>{number = 5, name = (null)}
2:<NSThread: 0x600000857380>{number = 6, name = (null)}
====1:<NSThread: 0x600000801a00>{number = 5, name = (null)}
----2:<NSThread: 0x6000008019c0>{number = 3, name = (null)}
====2:<NSThread: 0x6000008019c0>{number = 3, name = (null)}
----3:<NSThread: 0x600000812840>{number = 4, name = (null)}
====3:<NSThread: 0x600000812840>{number = 4, name = (null)}
*/
/*con_queue1
----1:<NSThread: 0x600001a20b00>{number = 5, name = (null)}
2:<NSThread: 0x600001a36800>{number = 3, name = (null)}
----3:<NSThread: 0x600001a367c0>{number = 4, name = (null)}
----2:<NSThread: 0x600001a34c40>{number = 6, name = (null)}
====1:<NSThread: 0x600001a20b00>{number = 5, name = (null)}
====2:<NSThread: 0x600001a34c40>{number = 6, name = (null)}
====3:<NSThread: 0x600001a367c0>{number = 4, name = (null)}
*/

相关文章

  • GCD任务、队列、线程看我就够了

    GCD开源地址[https://opensource.apple.com/release/macos-10141....

  • 学习GCD看我就够了

    学习GCD看我就够了 学习GCD看我就够了

  • 06进阶之路-多线程管理

    1. GCD相关 学习链接 GCD 简介 (多核编程管理线程) GCD 任务和队列(同步和异步任务 并发和串行队列...

  • GCD的简单使用

    GCD简单使用 GC使用就2个步骤 定制任务 将任务添加到队列中,gcd会自动将队列中的任务取出,放到对应的线程中...

  • iOS 中线程与队列的关系

    主线程主队列? 结论:GCD的主线程任务总会再最后执行。除GCD外的任务顺序执行。原因呢? 主线程是只有一个主队列...

  • GCD的基本使用

    GCD 多核编程、自动管理线程的生命周期(创建线程,调度任务,销毁线程) 一、GCD 的【任务】与【队列】 1.任...

  • 多线程

    iOS中的几种多线程GCD1、GCD分为任务和队列,任务(同步,异步)队列(串行,并发),同步串行,同步主队列的情...

  • iOS开发多线程之GCD

    iOS开发多线程之GCDiOS开发之GCD同步任务加强iOS开发之GCD串行队列iOS开发之GCD并发队列 GCD...

  • gcd多线程任务与队列组合分析

    关于gcd中串行队列并行队列,以及同步任务和异步任务的花式嵌套,分析执行结果 多线程调试常用代码: gcd的任务 ...

  • iOS开发之GCD并发队列

    iOS开发多线程之GCDiOS开发之GCD同步任务加强iOS开发之GCD串行队列iOS开发之GCD并发队列 03 ...

网友评论

      本文标题:GCD任务、队列、线程看我就够了

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