美文网首页
iOS多线程(一)

iOS多线程(一)

作者: 大虾咪 | 来源:发表于2021-08-15 14:40 被阅读0次

1.常见术语 --- 同步、异步、并发、串行

1.1同步和异步主要影响:能不能开启新的线程

  同步:在当前线程中执行任务,不具备开启新线程的能力
  异步:在新的线程中执行任务,具备开启新的线程的能力

1.2并发和串行主要影响:任务的执行方式

  并发:多个任务并发(同是)执行
  串行:一个任务执行完毕后在执行下一个任务

2、各种队列的执行效果

并发队列 手动创建的串行队列 主队列
同步(sync) 1.没有开启新线程 2.串行执行任务 1.没有开启新线程 2.串行执行任务 1.没有开启新线程 2.串行执行任务
异步 (async) 1.有开启新线程2.并发执行任务 1.有开启新线程2.串行执行任务 1.没有开启新线程 2.串行执行

3、使用sync函数往当前串行队列中添加任务,会卡住当前的串行队列(产生死锁)

4.详细分析实例如下代码

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController


// dispatch_sync和dispatch_async用来控制是否要开启新的线程

/**
 队列的类型,决定了任务的执行方式(并发、串行)
 1.并发队列
 2.串行队列
 3.主队列(也是一个串行队列)
 */

- (void)interview01
{
    // 问题:以下代码是在主线程执行的,会不会产生死锁?会!
    NSLog(@"执行任务1");
    
    dispatch_queue_t queue = dispatch_get_main_queue();
    dispatch_sync(queue, ^{
        NSLog(@"执行任务2");
    });
    
    NSLog(@"执行任务3");
    
     /*
        主线程                 主队列
      | 任务1     |           | viewDidLoad     |
      | sync任务2 |           | 任务2            |
      | 任务3     |
      队列的特点FIFO 先进先出 viewDidLoad执行结束后 主线程取出任务2执行
      任务2 要等待viewDidLoad  结束 导致任务2没法执行 任务3 也无法执行
      */
    
    // dispatch_sync立马在当前线程同步执行任务
}

- (void)interview02
{
    // 问题:以下代码是在主线程执行的,会不会产生死锁?不会!
    NSLog(@"执行任务1");
    
    dispatch_queue_t queue = dispatch_get_main_queue();
    dispatch_async(queue, ^{
        NSLog(@"执行任务2");
    });
    
    NSLog(@"执行任务3");
    
    // dispatch_async不要求立马在当前线程同步执行任务
}

- (void)interview03
{
    // 问题:以下代码是在主线程执行的,会不会产生死锁?会!
    NSLog(@"执行任务1");
    
    dispatch_queue_t queue = dispatch_queue_create("myqueu", DISPATCH_QUEUE_SERIAL);
    dispatch_async(queue, ^{ // block0
        NSLog(@"执行任务2");
        
        dispatch_sync(queue, ^{ // block1
            NSLog(@"执行任务3");
        });
    
        NSLog(@"执行任务4");
    });
    
    NSLog(@"执行任务5");
    /* 只分析 任务block0 任务block1
       子线程                   串行队列
     | 任务1      |           | block0     |
     | async任务2 |           | block1     |
     | sync任务3  |
     | 任务4      |
     | 任务5      |
     
     block0执行完才执行block1
     (dispatch_sync(queue, ^{ // block1 ) sync要求在当前线程执行block1
     前提条件block0在队列中执行完毕
     block0要执行完的前提是 block1 和 任务4要执行完毕 即整个block0 执行结束 block1才能拿出来执行
     产生死锁
     
     */
    //block0 和 block1 添加到同一个子线程 串行执行 任务block0拿到队列上执行 包含block1 执行不结束
    //block1 执行 等待任务block0执行完毕  死锁
}

- (void)interview04
{
    // 问题:以下代码是在主线程执行的,会不会产生死锁?不会!
    NSLog(@"执行任务1");
    
    dispatch_queue_t queue = dispatch_queue_create("myqueu", DISPATCH_QUEUE_SERIAL);
//    dispatch_queue_t queue2 = dispatch_queue_create("myqueu2", DISPATCH_QUEUE_CONCURRENT);
    dispatch_queue_t queue2 = dispatch_queue_create("myqueu2", DISPATCH_QUEUE_SERIAL);
    
    dispatch_async(queue, ^{ // 0
        NSLog(@"执行任务2");
        
        dispatch_sync(queue2, ^{ // 1
            NSLog(@"执行任务3");
        });
        
        NSLog(@"执行任务4");
    });
    
    NSLog(@"执行任务5");
    //  线程[66474:5109860] 执行任务1
    //  线程[66474:5109860] 执行任务5
    //  线程[66474:5110531] 执行任务2
    //  线程[66474:5110531] 执行任务3
    //  线程[66474:5110531] 执行任务4
}

- (void)interview05
{
    // 问题:以下代码是在主线程执行的,会不会产生死锁?不会!
    NSLog(@"执行任务1");
    
    dispatch_queue_t queue = dispatch_queue_create("myqueu", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_async(queue, ^{ // 0
        NSLog(@"执行任务2");
        
        dispatch_sync(queue, ^{ // 1
            NSLog(@"执行任务3");
        });
        
        NSLog(@"执行任务4");
    });
    
    NSLog(@"执行任务5");
    
    // 线程[66339:5106559] 执行任务1
    // 线程[66339:5106559] 执行任务5
    // 线程[66339:5107203] 执行任务2
    // 线程[66339:5107203] 执行任务3
    // 线程[66339:5107203] 执行任务4

}

- (void)viewDidLoad {
    [super viewDidLoad];
    
//    [self interview05];
    
    dispatch_queue_t queue1 = dispatch_get_global_queue(0, 0);
    dispatch_queue_t queue2 = dispatch_get_global_queue(0, 0);
    dispatch_queue_t queue3 = dispatch_queue_create("queu3", DISPATCH_QUEUE_CONCURRENT);
    dispatch_queue_t queue4 = dispatch_queue_create("queu4", DISPATCH_QUEUE_CONCURRENT);
    dispatch_queue_t queue5 = dispatch_queue_create("queu5", DISPATCH_QUEUE_CONCURRENT);
    
    NSLog(@"%p %p %p %p %p", queue1, queue2, queue3, queue4, queue5);
    //线程[66207:5103539] 0x1053ff080 0x1053ff080 0x600002279080 0x60000227a300 0x600002278b80
    //dispatch_get_global_queue 地址相同 全局只有一个全局队列
}


@end

相关文章

网友评论

      本文标题:iOS多线程(一)

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