C++ 线程(串行 并行 同步 异步)详解
发布时间 - 2026-01-11 02:09:04 点击率:次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任务同时执行,系统为其分配线程。图中的例子因第一个异步操作在第二个开始前已经结束了,所以并不是多少个异步操作就创建多少线程,主要还是看需要。
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
# C++
# 线程(串行
# 并行
# 同步
# 异步)
# 线程异步
# C++中的并行与并发基础与使用详解
# C++实现并行计算的两种方式
# 都是
# 一句
# 是在
# 第一个
# 多个
# 那句
# 只有一个
# 有一
# 就在
# 第二个
# 可以看出
# 句话
# 做完
# 就可以
# 的是
# 就会
# 如果你
# 会有
# 我还
# 看了
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?
php静态变量怎么调试_php静态变量作用域调试技巧【解答】
Laravel怎么实现前端Toast弹窗提示_Laravel Session闪存数据Flash传递给前端【方法】
桂林网站制作公司有哪些,桂林马拉松怎么报名?
Laravel N+1查询问题如何解决_Eloquent预加载(Eager Loading)优化数据库查询
Python文件操作最佳实践_稳定性说明【指导】
利用python获取某年中每个月的第一天和最后一天
php json中文编码为null的解决办法
千库网官网入口推荐 千库网设计创意平台入口
ChatGPT回答中断怎么办 引导AI继续输出完整内容的方法
百度浏览器网页无法复制文字怎么办 百度浏览器复制修复
SQL查询语句优化的实用方法总结
Laravel怎么返回JSON格式数据_Laravel API资源Response响应格式化【技巧】
网站建设要注意的标准 促进网站用户好感度!
青岛网站建设如何选择本地服务器?
最好的网站制作公司,网购哪个网站口碑最好,推荐几个?谢谢?
Laravel如何清理系统缓存命令_Laravel清除路由配置及视图缓存的方法【总结】
Laravel队列由Redis驱动怎么配置_Laravel Redis队列使用教程
如何快速搭建高效WAP手机网站吸引移动用户?
香港代理服务器配置指南:高匿IP选择、跨境加速与SEO优化技巧
在centOS 7安装mysql 5.7的详细教程
如何确认建站备案号应放置的具体位置?
Laravel Sail是什么_基于Docker的Laravel本地开发环境Sail入门
Laravel Eloquent关联是什么_Laravel模型一对一与一对多关系精讲
Windows驱动无法加载错误解决方法_驱动签名验证失败处理步骤
简单实现Android文件上传
Laravel Eloquent模型如何创建_Laravel ORM基础之Model创建与使用教程
微信小程序 配置文件详细介绍
Laravel如何发送邮件_Laravel Mailables构建与发送邮件的简明教程
软银砸40亿美元收购DigitalBridge 强化AI资料中心布局
WordPress 子目录安装中正确处理脚本路径的完整指南
如何安全更换建站之星模板并保留数据?
标题:Vue + Vuex + JWT 身份认证的正确实践与常见误区解析
Laravel控制器是什么_Laravel MVC架构中Controller的作用与实践
C++用Dijkstra(迪杰斯特拉)算法求最短路径
利用JavaScript实现拖拽改变元素大小
文字头像制作网站推荐软件,醒图能自动配文字吗?
香港服务器网站测试全流程:性能评估、SEO加载与移动适配优化
html如何与html链接_实现多个HTML页面互相链接【互相】
非常酷的网站设计制作软件,酷培ai教育官方网站?
Laravel如何记录日志_Laravel Logging系统配置与自定义日志通道
EditPlus中的正则表达式 实战(4)
java获取注册ip实例
详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)
如何在云虚拟主机上快速搭建个人网站?
Python文本处理实践_日志清洗解析【指导】
Laravel如何实现全文搜索功能?(Scout和Algolia示例)
Android自定义listview布局实现上拉加载下拉刷新功能
Laravel的Blade指令怎么自定义_创建你自己的Laravel Blade Directives
*服务器网站为何频现安全漏洞?

