美文网首页iOS基础与进阶
iOS开发中的并发、串行队列,同步、异步任务

iOS开发中的并发、串行队列,同步、异步任务

作者: 梁森的简书 | 来源:发表于2018-09-28 22:33 被阅读42次

在多线程开发中我们经常会遇到这些概念:并发队列、串行队列、同步任务、异步任务。我们将这四个概念进行组合会有四种结果:串行队列+同步任务、串行队列+异步任务、并发队列+同步任务、并发队列+异步任务。我们对这四种结果进行解释:
1.串行队列+同步任务:不会开启新的线程,任务逐步完成。
2.串行队列+异步任务:开启新的线程,任务逐步完成。
3.并发队列+同步任务:不会开启新的线程,任务逐步完成。
4.并发队列+异步任务:开启新的线程,任务同步完成。
我们如果要让任务在新的线程中完成,应该使用异步线程。为了提高效率,我们还应该将任务放在并发队列中。因此在开发中使用最多的是并发队列+异步任务。看代码:

  // 串行队列+同步任务

- (void)serialSyn{

dispatch_queue_t queue =dispatch_queue_create("serial",DISPATCH_QUEUE_SERIAL);

dispatch_sync(queue, ^{

    for (int i =0; i <3;
 i ++) {

        NSLog(@"1---%@", [NSThreadcurrentThread]);

    }

});

dispatch_sync(queue, ^{

    for (int i =0; i <3;
 i ++) {

        NSLog(@"2---%@", [NSThreadcurrentThread]);

    }

});

dispatch_sync(queue, ^{

    for (int i =0; i <3;
 i ++) {

        NSLog(@"3---%@", [NSThreadcurrentThread]);

    }

});

}

// 串行队列+异步任务

- (void)serialAsyn{

dispatch_queue_t queue =dispatch_queue_create("serial",DISPATCH_QUEUE_SERIAL);

dispatch_async(queue, ^{

    for (int i =0; i <3;
 i ++) {

        NSLog(@"1---%@", [NSThreadcurrentThread]);

    }

});

dispatch_async(queue, ^{

    for (int i =0; i <3;
 i ++) {

        NSLog(@"2---%@", [NSThreadcurrentThread]);

    }

});

dispatch_async(queue, ^{

    for (int i =0; i <3;
 i ++) {

        NSLog(@"3---%@", [NSThreadcurrentThread]);

    }

});

}

// 并发队列+同步任务

- (void)concurrenSyn{

dispatch_queue_t queue =dispatch_queue_create("concurrent",DISPATCH_QUEUE_CONCURRENT);

dispatch_sync(queue, ^{

    for (int i =0; i <3;
 i ++) {

        NSLog(@"1---%@", [NSThreadcurrentThread]);

    }

});

dispatch_sync(queue, ^{

    for (int i =0; i <3;
 i ++) {

        NSLog(@"2---%@", [NSThreadcurrentThread]);

    }

});

dispatch_sync(queue, ^{

    for (int i =0; i <3;
 i ++) {

        NSLog(@"3---%@", [NSThreadcurrentThread]);

    }

});



}

// 并发队列+异步任务

- (void)concurrentAsyn{

dispatch_queue_t queue =dispatch_queue_create("concurrent",DISPATCH_QUEUE_SERIAL);

dispatch_async(queue, ^{

    for (int i =0; i <3;
 i ++) {

        NSLog(@"1---%@", [NSThreadcurrentThread]);

    }

});

dispatch_async(queue, ^{

    for (int i =0; i <3;
 i ++) {

        NSLog(@"2---%@", [NSThreadcurrentThread]);

    }

});

dispatch_async(queue, ^{

    for (int i =0; i <3;
 i ++) {

        NSLog(@"3---%@", [NSThreadcurrentThread]);

    }

});

}

输出结果分别为:

  // 串行队列+同步任务


2017-12-09 15:50:18.427989+0800 GCD[1044:27175] 1---<NSThread: 0x600000073600>{number = 1, name = main}

2017-12-09 15:50:20.912799+0800 GCD[1044:27277] XPC connection interrupted

2017-12-09 15:50:21.429204+0800 GCD[1044:27175] 1---<NSThread: 0x600000073600>{number = 1, name = main}

2017-12-09 15:50:24.430559+0800 GCD[1044:27175] 1---<NSThread: 0x600000073600>{number = 1, name = main}

2017-12-09 15:50:25.431937+0800 GCD[1044:27175] 2---<NSThread: 0x600000073600>{number = 1, name = main}

2017-12-09 15:50:26.433460+0800 GCD[1044:27175] 2---<NSThread: 0x600000073600>{number = 1, name = main}

2017-12-09 15:50:27.433913+0800 GCD[1044:27175] 2---<NSThread: 0x600000073600>{number = 1, name = main}

2017-12-09 15:50:28.435443+0800 GCD[1044:27175] 3---<NSThread: 0x600000073600>{number = 1, name = main}

2017-12-09 15:50:29.435987+0800 GCD[1044:27175] 3---<NSThread: 0x600000073600>{number = 1, name = main}

2017-12-09 15:50:30.437512+0800 GCD[1044:27175] 3---<NSThread: 0x600000073600>{number = 1, name = main}

// 串行队列+异步任务


2017-12-09 16:08:03.242688+0800 GCD[1252:41773] 1---<NSThread: 0x600000276ec0>{number = 3, name = (null)}

2017-12-09 16:08:06.246989+0800 GCD[1252:41773] 1---<NSThread: 0x600000276ec0>{number = 3, name = (null)}

2017-12-09 16:08:09.249206+0800 GCD[1252:41773] 1---<NSThread: 0x600000276ec0>{number = 3, name = (null)}

2017-12-09 16:08:10.250193+0800 GCD[1252:41773] 2---<NSThread: 0x600000276ec0>{number = 3, name = (null)}

2017-12-09 16:08:11.250878+0800 GCD[1252:41773] 2---<NSThread: 0x600000276ec0>{number = 3, name = (null)}

2017-12-09 16:08:12.255908+0800 GCD[1252:41773] 2---<NSThread: 0x600000276ec0>{number = 3, name = (null)}

2017-12-09 16:08:13.258215+0800 GCD[1252:41773] 3---<NSThread: 0x600000276ec0>{number = 3, name = (null)}

2017-12-09 16:08:14.258708+0800 GCD[1252:41773] 3---<NSThread: 0x600000276ec0>{number = 3, name = (null)}

2017-12-09 16:08:15.259192+0800 GCD[1252:41773] 3---<NSThread: 0x600000276ec0>{number = 3, name = (null)}

// 串行队列+异步任务




2017-12-09 16:09:23.548551+0800 GCD[1283:42913] 1---<NSThread: 0x604000260540>{number = 1, name = main}

2017-12-09 16:09:25.547003+0800 GCD[1283:43153] XPC connection interrupted

2017-12-09 16:09:26.549830+0800 GCD[1283:42913] 1---<NSThread: 0x604000260540>{number = 1, name = main}

2017-12-09 16:09:29.550406+0800 GCD[1283:42913] 1---<NSThread: 0x604000260540>{number = 1, name = main}

2017-12-09 16:09:30.551134+0800 GCD[1283:42913] 2---<NSThread: 0x604000260540>{number = 1, name = main}

2017-12-09 16:09:31.552655+0800 GCD[1283:42913] 2---<NSThread: 0x604000260540>{number = 1, name = main}

2017-12-09 16:09:32.553861+0800 GCD[1283:42913] 2---<NSThread: 0x604000260540>{number = 1, name = main}

2017-12-09 16:09:33.555326+0800 GCD[1283:42913] 3---<NSThread: 0x604000260540>{number = 1, name = main}

2017-12-09 16:09:34.555842+0800 GCD[1283:42913] 3---<NSThread: 0x604000260540>{number = 1, name = main}

2017-12-09 16:09:35.556267+0800 GCD[1283:42913] 3---<NSThread: 0x604000260540>{number = 1, name = main}



// 并发队列+异步任务


2017-12-09 16:10:26.676320+0800 GCD[1309:44938] 3---<NSThread: 0x604000466c40>{number = 3, name = (null)}

2017-12-09 16:10:26.676320+0800 GCD[1309:44937] 2---<NSThread: 0x60000066e380>{number = 4, name = (null)}

2017-12-09 16:10:27.678310+0800 GCD[1309:44938] 3---<NSThread: 0x604000466c40>{number = 3, name = (null)}

2017-12-09 16:10:27.678316+0800 GCD[1309:44937] 2---<NSThread: 0x60000066e380>{number = 4, name = (null)}

2017-12-09 16:10:28.674756+0800 GCD[1309:44935] 1---<NSThread: 0x60000066fa80>{number = 5, name = (null)}

2017-12-09 16:10:28.679805+0800 GCD[1309:44938] 3---<NSThread: 0x604000466c40>{number = 3, name = (null)}

2017-12-09 16:10:28.679798+0800 GCD[1309:44937] 2---<NSThread: 0x60000066e380>{number = 4, name = (null)}

2017-12-09 16:10:31.675355+0800 GCD[1309:44935] 1---<NSThread: 0x60000066fa80>{number = 5, name = (null)}

2017-12-09 16:10:34.678046+0800 GCD[1309:44935] 1---<NSThread: 0x60000066fa80>{number = 5, name = (null)}

看表格:

0.png

注意:

在主队列中添加同步任务会产生死锁,进而导致程序崩溃。
代码:

- (void)viewDidLoad {
[super  viewDidLoad];
    NSLog(@"===========1");
    dispatch_sync(dispatch_get_main_queue(), ^{
   NSLog(@"===========2");
});
NSLog(@"===========3");

}

以上代码在打印出1之后就卡死在了dispatch_sync...的代码上。


串行队列异步任务中嵌套同步任务出现死锁

   // 创建同步队列
dispatch_queue_t queue = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL);
// 异步任务中嵌套同步任务
dispatch_async(queue, ^{
   
    NSLog(@"====2");
    // 无法打印5和3  死锁
    dispatch_sync(queue, ^{
        NSLog(@"====5");
    });
    
    NSLog(@"=====3");
});
NSLog(@"=====4");

本文来自 梁森森 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/u010105969/article/details/69914369?utm_source=copy

相关文章

  • 多线程

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

  • iOS GCD笔记

    串行队列 并发队列 主队列 全局并发队列 同步执行 异步执行 同步+并发队列 = 没有开启新线程,串行执行任务 s...

  • GCD学习总结

    GCD容易混淆的概念 任务,同步,异步 ,串行队列,并发队列 任务就是要做的事情 同步和异步是用来执行任务的 串行...

  • GCD小总结

    单例模式 串行队列同步/异步执行任务 并发队列同步/异步执行任务 队列组 延时执行 barrier

  • iOS开发之GCD并发队列

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

  • iOS线程、队列与死锁

    iOS中关于线程和队列,有一些概念:队列、串行队列、并发队列、主线程、主队列、任务、同步、异步。这些概念的意义和联...

  • OS And iOS — GCD基础

    主观感受 我们在多线程开发中我们经常会遇到这些概念:并发队列、串行队列、同步任务、异步任务。将这两种队列和同步、异...

  • GCD的几种创建方式及基本使用

    同步函数 同步函数+主队列 同步函数+串行队列 同步函数+并发队列 异步函数 异步函数+主队列 异步函数+串行队列...

  • 多线程GCD笔记

    同步函数 + 主队列 异步函数 + 主队列 同步函数 + 串行队列 异步函数 + 串行队列 同步函数 + 并发队列...

  • iOS开发多线程之GCD

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

网友评论

    本文标题:iOS开发中的并发、串行队列,同步、异步任务

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