iOS 多线程 swift5 GCD 自己消化的
文章目录
- 1.串行并行,同步异步
- 1.1 串行队列 + 同步执行
- 主队列:死锁
- 自定义串行队列:顺序执行,和正常执行代码一样
- 1.2 并行队列 + 同步执行:不开启线程,按代码顺序执行
- 1.3 串行队列 + 异步执行:一般只会新开一个线程
- 自定义串行队列:开启新线程,几个新线程中的任务和主线程中的任务并发执行
- 主队列:不开启新线程,会被放到最后面
- 1.4 并发队列(自定义) + 异步执行
- 动画
- 代码1: for循环在queue.async里
- 代码2:queue.async在for循环里
- 1.5 串行和同步的区别:串行是按任务添加的先后顺序执行,同步是按代码书写(执行)的顺序执行
- 1.6 其他实例测试
- 实例一
- 实例二
- 实例三
- 参考博客:
- 疑问:
1.串行并行,同步异步
- 并行队列同步执行,串行队列同步和异步执行,执行顺序是确定的
1.1 串行队列 + 同步执行
主队列:死锁
自定义串行队列:顺序执行,和正常执行代码一样
override func viewDidLoad() {super.viewDidLoad()print("start:\(Thread.current)")syncSerial()sleep(3)print("end:\(Thread.current)")}//串行队列 + 同步执行func syncSerial() {let serialQueue = DispatchQueue(label: "serial")for i in 0...10 {serialQueue.sync {print("\(i):\(Thread.current)")}}}
打印结果:
start:<NSThread: 0x600003f906c0>{number = 1, name = main}
0:<NSThread: 0x600003f906c0>{number = 1, name = main}
1:<NSThread: 0x600003f906c0>{number = 1, name = main}
2:<NSThread: 0x600003f906c0>{number = 1, name = main}
3:<NSThread: 0x600003f906c0>{number = 1, name = main}
4:<NSThread: 0x600003f906c0>{number = 1, name = main}
5:<NSThread: 0x600003f906c0>{number = 1, name = main}
6:<NSThread: 0x600003f906c0>{number = 1, name = main}
7:<NSThread: 0x600003f906c0>{number = 1, name = main}
8:<NSThread: 0x600003f906c0>{number = 1, name = main}
9:<NSThread: 0x600003f906c0>{number = 1, name = main}
10:<NSThread: 0x600003f906c0>{number = 1, name = main}
end:<NSThread: 0x600003f906c0>{number = 1, name = main}
1.2 并行队列 + 同步执行:不开启线程,按代码顺序执行
1.3 串行队列 + 异步执行:一般只会新开一个线程
自定义串行队列:开启新线程,几个新线程中的任务和主线程中的任务并发执行
- end什么时候打印不确定
override func viewDidLoad() {super.viewDidLoad()print("start:\(Thread.current)")asyncSerial()print("end:\(Thread.current)")}//串行队列 + 异步执行func asyncSerial(){let serialQueue = DispatchQueue(label: "serial")for i in 0...10 {serialQueue.async {print("\(i):\(Thread.current)")}}}
打印结果:
start:<NSThread: 0x6000033cc900>{number = 1, name = main}
0:<NSThread: 0x60000338c340>{number = 3, name = (null)}
end:<NSThread: 0x6000033cc900>{number = 1, name = main}
1:<NSThread: 0x60000338c340>{number = 3, name = (null)}
2:<NSThread: 0x60000338c340>{number = 3, name = (null)}
3:<NSThread: 0x60000338c340>{number = 3, name = (null)}
4:<NSThread: 0x60000338c340>{number = 3, name = (null)}
5:<NSThread: 0x60000338c340>{number = 3, name = (null)}
6:<NSThread: 0x60000338c340>{number = 3, name = (null)}
7:<NSThread: 0x60000338c340>{number = 3, name = (null)}
8:<NSThread: 0x60000338c340>{number = 3, name = (null)}
9:<NSThread: 0x60000338c340>{number = 3, name = (null)}
10:<NSThread: 0x60000338c340>{number = 3, name = (null)}
主队列:不开启新线程,会被放到最后面
- 执行顺序始终是:start -> end -> 然后按顺序执行for循环里的任务
override func viewDidLoad() {super.viewDidLoad()print("start:\(Thread.current)")asyncSerial()sleep(3)print("end:\(Thread.current)")}//串行队列 + 异步执行func asyncSerial(){let serialQueue = DispatchQueue.mainfor i in 0...10 {serialQueue.async {print("\(i):\(Thread.current)")}}}
1.4 并发队列(自定义) + 异步执行
动画
- 并行队列异步执行:执行顺序不确定
代码1: for循环在queue.async里
- print(“end:(Thread.current)”)什么时候执行是不确定的
- 并发队列中只添加了一任务,这个任务是按顺序执行的,始终会按顺序打印出i
override func viewDidLoad() {super.viewDidLoad()print("start:\(Thread.current)")asyncConcurrent()sleep(1)print("end:\(Thread.current)")}//并发队列 + 异步执行func asyncConcurrent(){let queue = DispatchQueue(label: "concurrence", qos: .userInteractive, attributes: .concurrent, autoreleaseFrequency: .inherit, target: nil)queue.async {for i in 0...10 {print("\(i):\(Thread.current)")}}}
打印结果:
start:<NSThread: 0x6000018d4440>{number = 1, name = main}
0:<NSThread: 0x60000188cbc0>{number = 6, name = (null)}
1:<NSThread: 0x60000188cbc0>{number = 6, name = (null)}
2:<NSThread: 0x60000188cbc0>{number = 6, name = (null)}
3:<NSThread: 0x60000188cbc0>{number = 6, name = (null)}
4:<NSThread: 0x60000188cbc0>{number = 6, name = (null)}
5:<NSThread: 0x60000188cbc0>{number = 6, name = (null)}
6:<NSThread: 0x60000188cbc0>{number = 6, name = (null)}
7:<NSThread: 0x60000188cbc0>{number = 6, name = (null)}
8:<NSThread: 0x60000188cbc0>{number = 6, name = (null)}
9:<NSThread: 0x60000188cbc0>{number = 6, name = (null)}
10:<NSThread: 0x60000188cbc0>{number = 6, name = (null)}
end:<NSThread: 0x6000018d4440>{number = 1, name = main}
注释掉sleep(1)后的打印结果
start:<NSThread: 0x60000253c800>{number = 1, name = main}
end:<NSThread: 0x60000253c800>{number = 1, name = main}
0:<NSThread: 0x600002560140>{number = 5, name = (null)}
1:<NSThread: 0x600002560140>{number = 5, name = (null)}
2:<NSThread: 0x600002560140>{number = 5, name = (null)}
3:<NSThread: 0x600002560140>{number = 5, name = (null)}
4:<NSThread: 0x600002560140>{number = 5, name = (null)}
5:<NSThread: 0x600002560140>{number = 5, name = (null)}
6:<NSThread: 0x600002560140>{number = 5, name = (null)}
7:<NSThread: 0x600002560140>{number = 5, name = (null)}
8:<NSThread: 0x600002560140>{number = 5, name = (null)}
9:<NSThread: 0x600002560140>{number = 5, name = (null)}
10:<NSThread: 0x600002560140>{number = 5, name = (null)}
代码2:queue.async在for循环里
- print(“end:(Thread.current)”)什么时候执行是不确定的
- 并发队列中的多个任务执行顺序不确定
//并发队列 + 异步执行func asyncConcurrent(){let queue = DispatchQueue(label: "concurrence", qos: .userInteractive, attributes: .concurrent, autoreleaseFrequency: .inherit, target: nil)print("start:\(Thread.current)")for i in 0...100 {queue.async {print("\(i):\(Thread.current)")}}print("end:\(Thread.current)")}
打印结果:
start:<NSThread: 0x600003ac48c0>{number = 1, name = main}
0:<NSThread: 0x600003a86600>{number = 4, name = (null)}
1:<NSThread: 0x600003a8dec0>{number = 5, name = (null)}
4:<NSThread: 0x600003a86600>{number = 4, name = (null)}
2:<NSThread: 0x600003aa66c0>{number = 7, name = (null)}
6:<NSThread: 0x600003a8dec0>{number = 5, name = (null)}
5:<NSThread: 0x600003a98b80>{number = 3, name = (null)}
3:<NSThread: 0x600003aa0640>{number = 8, name = (null)}
7:<NSThread: 0x600003aa66c0>{number = 7, name = (null)}
8:<NSThread: 0x600003aa0640>{number = 8, name = (null)}
9:<NSThread: 0x600003aa66c0>{number = 7, name = (null)}
10:<NSThread: 0x600003a98b80>{number = 3, name = (null)}
11:<NSThread: 0x600003a98b80>{number = 3, name = (null)}
12:<NSThread: 0x600003aa66c0>{number = 7, name = (null)}
13:<NSThread: 0x600003a98b80>{number = 3, name = (null)}
14:<NSThread: 0x600003a8dec0>{number = 5, name = (null)}
15:<NSThread: 0x600003aa66c0>{number = 7, name = (null)}
16:<NSThread: 0x600003a98b80>{number = 3, name = (null)}
17:<NSThread: 0x600003aa66c0>{number = 7, name = (null)}
18:<NSThread: 0x600003a98b80>{number = 3, name = (null)}
19:<NSThread: 0x600003a8dec0>{number = 5, name = (null)}
20:<NSThread: 0x600003a86600>{number = 4, name = (null)}
21:<NSThread: 0x600003a8dec0>{number = 5, name = (null)}
22:<NSThread: 0x600003a98b80>{number = 3, name = (null)}
24:<NSThread: 0x600003aa6380>{number = 9, name = (null)}
23:<NSThread: 0x600003aa66c0>{number = 7, name = (null)}
25:<NSThread: 0x600003aa0640>{number = 8, name = (null)}
26:<NSThread: 0x600003ab1ec0>{number = 10, name = (null)}
27:<NSThread: 0x600003aa6000>{number = 11, name = (null)}
89:<NSThread: 0x600003aa0640>{number = 8, name = (null)}
91:<NSThread: 0x600003aa6000>{number = 11, name = (null)}
30:<NSThread: 0x600003abd100>{number = 14, name = (null)}
92:<NSThread: 0x600003aa0640>{number = 8, name = (null)}
32:<NSThread: 0x600003aa7440>{number = 16, name = (null)}
33:<NSThread: 0x600003ab24c0>{number = 17, name = (null)}
95:<NSThread: 0x600003aa0640>{number = 8, name = (null)}
96:<NSThread: 0x600003aa7440>{number = 16, name = (null)}
35:<NSThread: 0x600003ab30c0>{number = 19, name = (null)}
97:<NSThread: 0x600003ab24c0>{number = 17, name = (null)}
38:<NSThread: 0x600003aa7540>{number = 22, name = (null)}
39:<NSThread: 0x600003abd2c0>{number = 23, name = (null)}
40:<NSThread: 0x600003a81040>{number = 24, name = (null)}
41:<NSThread: 0x600003ab1440>{number = 25, name = (null)}
42:<NSThread: 0x600003aa6580>{number = 26, name = (null)}
43:<NSThread: 0x600003a89040>{number = 27, name = (null)}
44:<NSThread: 0x600003ab15c0>{number = 28, name = (null)}
45:<NSThread: 0x600003abd580>{number = 29, name = (null)}
end:<NSThread: 0x600003ac48c0>{number = 1, name = main}
46:<NSThread: 0x600003aa7740>{number = 30, name = (null)}
47:<NSThread: 0x600003a8b700>{number = 31, name = (null)}
48:<NSThread: 0x600003abd640>{number = 32, name = (null)}
49:<NSThread: 0x600003aa7800>{number = 33, name = (null)}
50:<NSThread: 0x600003a8ad00>{number = 34, name = (null)}
51:<NSThread: 0x600003abd700>{number = 35, name = (null)}
52:<NSThread: 0x600003aa7a40>{number = 36, name = (null)}
53:<NSThread: 0x600003ab3bc0>{number = 37, name = (null)}
54:<NSThread: 0x600003abd7c0>{number = 38, name = (null)}
55:<NSThread: 0x600003aa7980>{number = 39, name = (null)}
56:<NSThread: 0x600003ab3d40>{number = 40, name = (null)}
57:<NSThread: 0x600003abd880>{number = 41, name = (null)}
58:<NSThread: 0x600003aa7880>{number = 42, name = (null)}
59:<NSThread: 0x600003ab3e40>{number = 43, name = (null)}
60:<NSThread: 0x600003a8a040>{number = 44, name = (null)}
61:<NSThread: 0x600003aaffc0>{number = 45, name = (null)}
62:<NSThread: 0x600003ab3e80>{number = 46, name = (null)}
63:<NSThread: 0x600003abd940>{number = 47, name = (null)}
64:<NSThread: 0x600003ab3f40>{number = 48, name = (null)}
65:<NSThread: 0x600003aaff00>{number = 49, name = (null)}
66:<NSThread: 0x600003abda40>{number = 50, name = (null)}
67:<NSThread: 0x600003ab1180>{number = 51, name = (null)}
68:<NSThread: 0x600003a8a100>{number = 52, name = (null)}
69:<NSThread: 0x600003aafe40>{number = 53, name = (null)}
70:<NSThread: 0x600003abdb00>{number = 54, name = (null)}
71:<NSThread: 0x600003a895c0>{number = 55, name = (null)}
72:<NSThread: 0x600003ab2080>{number = 56, name = (null)}
73:<NSThread: 0x600003abdbc0>{number = 57, name = (null)}
74:<NSThread: 0x600003aafd40>{number = 58, name = (null)}
75:<NSThread: 0x600003a89a40>{number = 59, name = (null)}
76:<NSThread: 0x600003abdc80>{number = 60, name = (null)}
77:<NSThread: 0x600003aafc40>{number = 61, name = (null)}
78:<NSThread: 0x600003a89180>{number = 62, name = (null)}
79:<NSThread: 0x600003aafb80>{number = 63, name = (null)}
80:<NSThread: 0x600003abdd40>{number = 64, name = (null)}
81:<NSThread: 0x600003a8bd00>{number = 65, name = (null)}
82:<NSThread: 0x600003aafac0>{number = 66, name = (null)}
83:<NSThread: 0x600003abde40>{number = 67, name = (null)}
84:<NSThread: 0x600003a86600>{number = 4, name = (null)}
85:<NSThread: 0x600003a8dec0>{number = 5, name = (null)}
86:<NSThread: 0x600003a98b80>{number = 3, name = (null)}
87:<NSThread: 0x600003aa6380>{number = 9, name = (null)}
88:<NSThread: 0x600003aa66c0>{number = 7, name = (null)}
28:<NSThread: 0x600003aa0000>{number = 12, name = (null)}
90:<NSThread: 0x600003ab1ec0>{number = 10, name = (null)}
29:<NSThread: 0x600003abd080>{number = 13, name = (null)}
31:<NSThread: 0x600003ab1b00>{number = 15, name = (null)}
93:<NSThread: 0x600003aa6000>{number = 11, name = (null)}
94:<NSThread: 0x600003abd100>{number = 14, name = (null)}
34:<NSThread: 0x600003abd1c0>{number = 18, name = (null)}
36:<NSThread: 0x600003aa73c0>{number = 20, name = (null)}
37:<NSThread: 0x600003abd280>{number = 21, name = (null)}
98:<NSThread: 0x600003aa0640>{number = 8, name = (null)}
100:<NSThread: 0x600003aa7440>{number = 16, name = (null)}
99:<NSThread: 0x600003ab30c0>{number = 19, name = (null)}
1.5 串行和同步的区别:串行是按任务添加的先后顺序执行,同步是按代码书写(执行)的顺序执行
- 在主队列中同步串行会发生死锁,就是因为这个两个执行顺序发生冲突,引起循环等待
1.6 其他实例测试
实例一
实例二
实例三
参考博客:
iOS线程间通信 - GCD篇
iOS线程间通信 - NSThread篇
iOS开发 swift5 – GCD
我的另外一篇博客:GCD
疑问:
1.同步并行会死锁吗
2.同步和串行的区别
iOS 多线程 swift5 GCD 自己消化的相关推荐
- iOS 多线程和GCD(Grand Central Dispath) 教程 (一)
iOS 多线程和GCD(Grand Central Dispath) 教程 (一) 本文翻译自 Ray Wenderlich 的博客 点击打开原文链接.全部由本人亲手翻译...童叟无欺~ 你有木有遇 ...
- iOS多线程-【GCD】
参考链接:https://www.jianshu.com/p/2d57c72016c6 博主总结的很好,个人理解的很清晰 1.GCD简介 因为 GCD 有很多好处啊,具体如下: GCD 可用于多核的并 ...
- IOS多线程使用GCD与信号量实现生产者与消费者模式
一.原理的简述 在生产者消费者模式当中,首先需要分清在这个模式当中有哪些角色? 各角色分别担任什么职责与它们之间的关系如何? 角色之间是在保证数据的准确性的情况下如何通信(同步数据)的? 假设现在有一 ...
- iOS 多线程:『GCD』详尽总结
原文链接:www.jianshu.com/p/2d57c7201- 感谢大家对这篇文章的喜欢和支持.为了不辜负大家的喜欢,也为了更好的让大家了解 iOS 多线程,以及 GCD 的相关知识,我对这篇文章 ...
- iOS多线程全套:线程生命周期,多线程的四种解决方案,线程安全问题,GCD的使用,NSOperation的使用(上)
2017-07-08 remember17 Cocoa开发者社区 目的 本文主要是分享iOS多线程的相关内容,为了更系统的讲解,将分为以下7个方面来展开描述. 多线程的基本概念 线程的状态与生命周期 ...
- iOS多线程开发之GCD(基础篇)
总纲: GCD基本概念 GCD如何实现 GCD如何使用 队列和任务组合 一.GCD基本概念 GCD 全称Grand Central Dispatch(大中枢队列调度),是一套低层API,提供了⼀种新的 ...
- iOS 多线程-GCD栅栏方法
iOS 多线程-GCD任务+队列. iOS 多线程-GCD队列组. iOS 多线程-GCD栅栏方法. 上一篇文章记录了队列组的使用,是为了处理多个任务之间的顺序.但是开发中会出现多组任务的顺序问题. ...
- iOS 多线程的四种技术方案
iOS 多线程的四种技术方案 image pthread 实现多线程操作 代码实现: void * run(void *param) {for (NSInteger i = 0; i < 100 ...
- iOS多线程:『NSOperation、NSOperationQueue』详尽总结
2019独角兽企业重金招聘Python工程师标准>>> iOS多线程:『NSOperation.NSOperationQueue』详尽总结 转载: 原地址https://www.ji ...
最新文章
- 概率链接nbu 2416 奇怪的散步
- 如何了解这个世界(社会)运行的本质
- 记一个bug定位与修复过程
- leetcode 496, 503, 556. Next Greater Element I, II, III | 496, 503, 556. 下一个更大元素 I,II,III(单调栈)
- 教你实践ASP.NET Core Authorization(免看文档教程)
- JAVA 1.7并发之LinkedTransferQueue原理理解
- 论文解读——Improving Object Detection With One Line of Code
- T-SQL语言(一)
- 排便的快感--不是非主流
- 2014大学计算机操作系统,郑州大学软件学院2013-2014《计算机操作系统》试题及答案...
- 分割 反比 权重图 梯度 灰度_numpy gradient梯度函数1
- Atitit opencv版本新特性attilax总结
- SAM2695 带效果器的低功耗单芯片合成器
- Java购票系统实训总结_Java 购票系统实现
- 如何使用DOSBox软件编写运行汇编语言程序
- java解指派问题,运用Excel规划求解解决指派问题
- 最全浏览器兼容性问题以及解决方案
- EINT DINT ERTM DRTM EALLOW EDIS ESTOP0的理解
- 王可欣作业一 统计软件简介与数据操作
- Efficientnet网络详解及构建
热门文章
- windows环境C++抓取dump信息
- python中的map怎么用_python中的map怎么使用(方法详解)
- 公路村村通(含注释)
- oracle表如何创建序列,Oracle中如何创建序列
- verilog 跨时钟域 单bit延迟打拍 多bit延迟采样 多bit计数延迟采样
- 2021-10-18使用eop烧写裸板程序
- 新手大战Android源码之启动过程
- Flutter 插件signature签字使用
- 深度优先搜索详解 C++实现
- python随机生成三位数字_五种方法实现python3-随机生成10位包含数字和字母的密码...