C++ 线程(串行 并行 同步 异步)详解
作者:Love@YR 发布时间:2023-07-18 18:09:43
C++ 线程(串行 并行 同步 异步)详解
看了很多关于这类的文章,一直没有总结。不总结的话就会一直糊里糊涂,以下描述都是自己理解的非官方语言,不一定严谨,可当作参考。
首先,进程可理解成一个可执行文件的执行过程。在ios app上的话我们可以理解为我们的app的.ipa文件执行过程也即app运行过程。杀掉app进程就杀掉了这个app在系统里运行所占的内存。
线程:线程是进程的最小单位。一个进程里至少有一个主线程。就是那个main thread。非常简单的app可能只需要一个主线程即UI线程。当然大部分还是会有一些子线程的,比如如果你用了AFNetWorking,你的请求都是开辟了子线程。
关于串行,并行,同步,异步,我还是以下面代码的方式做个说明。
首先button点击事件运行在主线程里,先是在主线程里做了打印了一句话,然后创建了一个串行或者并行的队列,之后连续创建了3个同步或者异步的block任务放入此队列中,最后再在主线程里打印一句话。
- (IBAction)serialSync:(id)sender {
NSLog(@"start log in main thread"]);
dispatch_queue_t myQueue = dispatch_queue_create("myQueue", NULL);
for (NSInteger n = 0; n < 3; n++) {
dispatch_sync(myQueue, ^{
for (NSInteger i = 0; i < 500000000; i++) {
if (i == 0) {
NSLog(@"串行同步任务%ld -> 开始%@",n,[NSThread currentThread]);
}
if (i == 499999999) {
NSLog(@"串行同步任务%ld -> 完成",(long)n);
}
}
});
}
NSLog(@"阻塞我没有?当前线程%@",[NSThread currentThread]);
}
- (IBAction)serialAsync:(id)sender {
NSLog(@"start log in main thread"]);
dispatch_queue_t myQueue = dispatch_queue_create("myQueue", NULL);//创建一个串行队列
for (NSInteger n = 0; n < 3; n++) {
dispatch_async(myQueue, ^{
for (NSInteger i = 0; i < 500000000; i++) {
if (i == 0) {
NSLog(@"串行异步任务%ld -> 开始%@",n,[NSThread currentThread]);
}
if (i == 499999999) {
NSLog(@"串行异步任务%ld -> 完成",(long)n);
}
}
});
}
NSLog(@"阻塞我没有?当前线程%@",[NSThread currentThread]);
}
- (IBAction)concurrentSync:(id)sender {
NSLog(@"start log in main thread"]);
dispatch_queue_t myQueue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
for (NSInteger n = 0; n < 3; n++) {
dispatch_sync(myQueue, ^{
for (NSInteger i = 0; i < 500000000; i++) {
if (i == 0) {
NSLog(@"并行同步任务%ld -> 开始%@",(long)n,[NSThread currentThread]);
}
if (i == 499999999) {
NSLog(@"并行同步任务%ld -> 完成",(long)n);
}
}
});
}
NSLog(@"阻塞我没有?当前线程%@",[NSThread currentThread]);
}
- (IBAction)concurrentAsync:(id)sender {
NSLog(@"start log in main thread"]);
dispatch_queue_t myQueue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
for (NSInteger n = 0; n < 3; n++) {
dispatch_async(myQueue, ^{
for (NSInteger i = 0; i < 500000000; i++) {
if (i == 0) {
NSLog(@"并行异步任务%ld -> 开始%@",n,[NSThread currentThread]);
}
if (i == 499999999) {
NSLog(@"并行异步任务%ld -> 完成",(long)n);
}
}
});
}
NSLog(@"阻塞我没有?当前线程%@",[NSThread currentThread]);
}
最后的结果如图:
其中我把第一句打印和最后一句打印用玫红色表示,它们都运行在当前线程。
方框表示队列,3个block任务分别为3种不同的颜色。
可以看出:
串行即上一个block任务执行完毕下一个任务才加入到队列中。
并行即其中的任务同时加入到队列中。
从运行结果来看
第一个图只有一个主线程:
3个block都是同步即都阻塞当前线程,所以最后那句打印的任务就在3个block运行完之后。
3个block又是串行,所以一个一个运行
第二个图有2个线程即一个主线程一个子线程:
3个block都是异步,没有任务阻塞当前线程。所以最后那句打印是在第一句打印后就可以开始执行的。
3个block都是异步,异步会创建新的线程即至少有一个子线程。
3个block是串行,只有一个任务做完才会加另一个任务入队列,所以只需一个子线程。
第三个图只有一个主线程:
3个block都是同步即都阻塞当前线程,所以最后那句打印的任务就在3个block运行完之后。
3个block是并行,同时被加入队列中。
3个block都是同步,由于同步意味着等待,所以任务的执行表现为顺序执行,其实是一起加进去的但是等待的,跟串行的区别是串行是别的任务做完才把它加进队列中。
第四个图有多个线程:
3个block都是异步,没有任务阻塞当前线程。所以最后那句打印是在第一句打印后就可以开始执行的。
3个block都是异步,异步会创建新的线程即至少有一个子线程。
3个block是并行,需创建多个子线程才能保证任务同时执行。
再看一张图:其中第一个异步为玫红色,两个同步分别以紫色黄色表示,两个异步分别以绿色棕色表示,队列后面的当前线程动作为橘色。虚线代表等待。上面代表串行,下面是并行。
由此图可以看出:
同步block会阻塞当前线程,即会在当前线程中运行。(这里的当前线程为主线程所以会看到UI卡住)
异步block会开辟新的线程。
在串行队列中,异步block任务用的是同一个子线程,因为需要等待任务一个一个地执行,不需要多个线程。
在并行队列中,异步block任务同时执行,系统为其分配线程。图中的例子因第一个异步操作在第二个开始前已经结束了,所以并不是多少个异步操作就创建多少线程,主要还是看需要。
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


猜你喜欢
- 1、WinForm中datagridview增加行号在界面上拖一个控件dataGridView1,在datagridview添加行事件中添加
- springboot项目部署平时我们在部署springboot打成jar方式部署得时候,大多数都会编写启动脚本,脚本有很多种写法,但大多数意
- 本文实例为大家分享了java就业信息管理平台开发案例,供大家参考,具体内容如下可查询公司信息,学生信息,班级信息,针对学生就业与否信息的统计
- 目录截屏AudioRecord音频采集MediaCodec编码音频数据Rtp发送数据SDP文件配置音频config配置计算方式:vlc测试播
- 本文实例讲述了C#域名解析简单实现方法。分享给大家供大家参考。具体实现方法如下:using System;using System.Coll
- Flutter自适应瀑布流前言:在电商app经常会看到首页商品推荐的瀑布流,或者类似短视频app首页也是瀑布流,这些都是需要自适应的,才能给
- 本文实例讲述了Android TextView跑马灯效果实现方法。分享给大家供大家参考,具体如下:public class MyTextVi
- 本文实例讲述了Android编程实现应用自动更新、下载、安装的方法。分享给大家供大家参考,具体如下:我们看到很多Android应用都具有自动
- 很多时候木马程序会伪装成其他格式的文件上传到网站,最常见的如图片格式。本文就以C#为例讲述C#判断上传文件是否是图片以防止木马上传的方法,具
- WebSocket介绍WebSocket是HTML5开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。在WebSocket API中
- AQS 同步队列1、AQS 介绍AQS 是 AbstractQueuedSynchronizer 的缩写,他是一个抽象同步类,为 JUC 包
- SpringMVC异常处理机制(一)项目前准备首先参照文章Spring课程工程构建+SpringMVC简介及其快速入门搭建项目搭建好一个项目
- 前言volatile相关的知识其实自己一直都是有掌握的,能大概讲出一些知识,例如:它可以保证可见性;禁止指令重排。这两个特性张口就来,但要再
- 一:算术运算符1.算术运算符有哪些①基本四则运算符:+ - * / %②增量赋值运算符:+= -= *= /= %=③自增/自减运算符++
- 简介Android Studio升级到3.0后,有不少的改动和新特性,先贴出官方的迁移说明。本文会持续收集与总结本人在使用Android S
- Dubbo服务暴露机制前言在进行服务暴露机制的分析之前,必须谈谈什么是URL,在Dubbo服务暴露过程中URL是无处不在的,贯穿了整个过程。
- 引言:最近在工作中遇到与某些API对接的post的数据需要将对象的字段首字母小写。解决办法有两种:第一种:使用对象的字段属性设置JsonPr
- 1、使用FileStream读写文件 文件头:using System;using System.Collections.Gene
- 1.鼠标右击我的电脑–》属性–》高级系统设置2.把下面的变量名称和电脑文件的本地路径填进去即可(注意:变量值后面后面不要带分号)jdk环境变
- Java 最初版本只为常用的数据结构提供了很少的一组类:Vector、Stack、Hashtable、BitSet 与 Enumeratio