协程锁组件
协程锁是因为异步编程总会引起逻辑上一些先后关系给破坏掉了。为了保证逻辑上先后关系 引入协程锁。就跟线程的lock一样
增加协程锁组件,locationComponent跟actor都使用协程锁来实现队列机制,代码大大简化,并且非常好懂。让消息可以队列处理而已
协程锁原理很简单,同一个key只有一个协程能执行,其它同一个key的协程将队列,这个协程执行完会唤醒下一个协程。
协程锁是个非常方便的组件,比如服务端在处理登录或者下线过程中,每个异步操作都可能同一个账号会再次登录上来,
逻辑十分复杂,我们会希望登录某部分异步操作是原子操作,账号再次登录要等这个原子操作完成才能执行,
这样登录或者下线过程逻辑复杂度将会简化十倍以上。协程锁是ET解决这类异步重入问题的大杀器。
5.0 分支是没有的. 现在5.0也有了。不过请使用6.0 的版本协程锁。
5.0协程锁没有超时,写出死锁的话找问题比较难,6.0会超时自动解锁,日志上更容易找问题
协程+协程锁才是使用协程的完全体,不然,逻辑重入真的会搞死人,特别是一连串的await,每个await后都可能有被其他协程修改的可能,很麻烦
unity也很有必要用协程锁啊,比如异步加载ab包,假如你不是切场景的时候加载完的ab包,在场景中又想异步加载,那非常有可能会同时两个协程去加载同一个ab包,这时候就出错了,用await就需要想下这些情况
如果不使用ettask+协程锁。资源加载代码绝对会写的很丑。et的resourcecomponent看起来十分简洁好懂
协程锁实际上是协程队列,task没有协程队列,用起来还是不那么舒爽的,搭配上协程队列,将直接起飞,以前很难写的东西,就变得非常非常简单了
举个客户端的例子,资源加载ab包,ab包假如使用异步加载,那可能出现一个协程正在加载ab包,还没加载完,另外协程又开始加载这个ab包,那就出问题了。我们显然希望第二个协程要等待第一个协程加载完成,再往下执行,这样可以判断这个包加载过了就不需要再加载了。所以resoursecomponent里面是有用到协程锁的
应该怎么避免死锁问题?
5.0协程锁没有超时,写出死锁的话找问题比较难,6.0会超时自动解锁,日志上更容易找问题
5.0会有死锁问题,所以我改进了一版,协程锁默认60秒,超过就抛异常。这时候你就要查查自己逻辑,有没有死锁了,但目前只在6.0有这个更新。
提交: e2099974e6810ea27e6d6383ead8f59e045310c7 提交时间: 2021年4月29日 23:23:02
1.无GC ETTask,其实是利用对象池,注意,必须小心使用,不懂不要乱用
2.超时协程锁,并且修复了一个协程锁队列递归调用导致堆栈溢出的bug
聊天记录: