博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于线程任务的一些思考
阅读量:5239 次
发布时间:2019-06-14

本文共 1056 字,大约阅读时间需要 3 分钟。

当某一个线程需要对一段代码或者数据进行访问的时候,为了保证不会有对个线程同时访问这段代码或者数据的情况,都会使用锁来做互斥。

线程A完全访问完代码(下面只说代码,数据是一样的)的时候,线程B才可以访问。如果线程B访问的时候,线程A正在访问,这个时候线程B会阻塞。太多的阻塞和锁会让效率下降。

仔细想一想,某个线程A访问一段代码到底是什么意思?

我的理解是当前整个系统状态下需要这段代码进行一次执行。

再继续想,难道我必须要求这段代码马上(相对于这个线程)执行吗?完全可以把这段代码的执行做成一个任务,丢到某个专门的线程C中执行。线程C循环查看队列中是否有需要执行的任务,当它看到线程A发送的任务后先执行,然后再回调线程A,这个回调也可以采用线程队列的方式,即把这个执行结果发送到线程A的队列中。这样各个线程只通过自己的消息队列互相协作,大大降低了耦合性。

这种模式也有很多不足的问题,比如线程A需要马上获悉这段代码的执行结果,然后下面的执行逻辑依赖于这个结果。

不过个人认为这种多线程的设计是不够好的,总是可以有办法来避免这样。退一步说,如果确实存在线程A需要马上获取执行结果的情况,也可以处理。线程A把这个任务设置优先级很高,然后就不断循环判断线程C是不是执行完这个任务了。假如这个时候线程C正在执行一个很耗时的任务,甚至可以让线程C先暂停当前任务的执行,执行完线程A的任务才去执行。这种情况不多见,主要会出现在一些实时系统中。

在我们游戏中,主要有两个线程。逻辑线程负责执行相关的脚本逻辑和生成渲染数据;渲染线程负责渲染和OpenGL接口调用。这两个都是循环线程。

当需要生成一个gl纹理的时候,逻辑线程获取相关图像数据,然后分派一个任务到渲染线程。渲染线程循环查看消息队列,发现有生成纹理的任务就执行,然后把结果放到逻辑线程的消息队列里面。

当需要渲染一组对象的时候,逻辑线程也使用相关数据生成一个任务放到渲染线程。渲染线程还可以定义优先级,决定是先渲染还是先生成纹理。

当渲染线程比较忙碌而逻辑线程比较空闲的时候,是不是一些计算可以放到逻辑线程中,毕竟玩家感受到的帧率取决于二者的最小值。

总之,这种消息队列的做法降低了耦合,增加了灵活性和健壮性。

把线程的概念抽象到一个更高层次的任务的概念,线程对代码的执行上升到线程需要某个任务一次执行的高度,看问题的层次高了,也会发现很多更优秀的设计。

转载于:https://www.cnblogs.com/zhangshuliai/p/7616113.html

你可能感兴趣的文章
【BZOJ4516】生成魔咒(后缀自动机)
查看>>
提高PHP性能的10条建议
查看>>
svn“Previous operation has not finished; run 'cleanup' if it was interrupted“报错的解决方法...
查看>>
熟用TableView
查看>>
Java大数——a^b + b^a
查看>>
poj 3164 最小树形图(朱刘算法)
查看>>
百度贴吧图片抓取工具
查看>>
服务器内存泄露 , 重启后恢复问题解决方案
查看>>
ajax post 传参
查看>>
2.1命令行和JSON的配置「深入浅出ASP.NET Core系列」
查看>>
android一些细节问题
查看>>
KDESVN中commit时出现containing working copy admin area is missing错误提示
查看>>
利用AOP写2PC框架(二)
查看>>
【动态规划】skiing
查看>>
java定时器的使用(Timer)
查看>>
Android实现静默安装与卸载
查看>>
ef codefirst VS里修改数据表结构后更新到数据库
查看>>
boost 同步定时器
查看>>
[ROS] Chinese MOOC || Chapter-4.4 Action
查看>>
简单的数据库操作
查看>>