编程规范---问题单同步
定位一个问题,花了1天左右时间,发现是之前另一个分支上已发现,而且已经提供了解决方案的问题
疑问:这样的问题,不应该花这些时间,如何改进?---------应该在主干和分支之间有定时的同步机制
1. 应该有主干和分支之间的同步流程
2. 这个时间不宜太长,因为太长问题单的修改可能都忘记了,容易出错-------定时同步的话
3. 或:随时有多个主干的环境,同样问题确认在其它环境上是否存在,存在则直接同步问题单-------------当前用禅道是否支持这些功能
完整的过程
1. 在K环境上发现,登录每次都失败(偶有成功),怀疑和最近的加密方式增加有关(合理怀疑,因为最近的主要合入是这个)
----------------最终确认不是这个原因
2. 通过增加日志,确认是由于竞争条件(某个线程同一时间只允许一个在运行,实际运行了多个,且第2个运行时,由于第1个未完全退出,导致仅设置了标识位,但未运行,然后后续的线程运行就不能正常启动了)
---------------当前缺少部分日志规范,日志打印的较少,较熟悉才可参根据日志判断
2.1. 线程1运行,将运行标识位置为运行中
2.2. 线程1运行结束前设置标识位为不再运行,并emit 信号,然后,return退出
2.3. 上述emit信号解发了线程2运行,线程2运行时检测到线程1的标识位是不再运行,因此,可以运行(满足同一时间只有1个进程运行的条件),因此开始运行,但此时,线程1的return尚未执行,导致其实际未运行,但标识位置为运行了
2.4. 后续其它线程运行时,检查标识位,由于标识位已由线程2置为运行中,因此,不会执行(同一时间只有一个实例),但线程2由于上述原因实际未执行,导致标识位一直无法置为不再运行,阻塞了后续所有线程
3. 按上述原因,重新设计一版线程的标识位,实际有一点问题
----emit是Qt的机制,这里emit肯定会导致后续的问题,所以
3.1. 延迟emit发送-----------可以解决问题,不严谨,这里后面的return执行的时机,不能保证在emit之前,因此,虽然可以解决问题,但不是从根本上
3.2. 重新设计标识位,采用autointer,确保多线程读到的是同一个------------未能解决问题,原因:emit发送会触发进程切换,仍然会走到老路上,会在设置运行标识位false之后,return之前emit,仍会导致问题
3.3. 重新设置标识位,增加锁,并增加进程的完整的状态检查--------------------------未尝试(这个应该是更好的一个方法),在同其它同事的交流过程中,得知其它分支已解决了类似的问题
3.4. 同步原分支的修改即可
4. 当前的改法及其局限
当前改法为:
4.1. 在可能的地方增加延时,并在延迟中判断进程是否仍在运行,如果运行,则继续等待
问题:
4.1. 等待的时间不定,可能需要实际测试
4.2. 这里的函数表义和实际不符,名字为:setSleepTime 实际上应该叫做 runAfterPreThreadFinished或类似,没有体现出这个意思。
4.3. 这里采用简单的方法,虽然能解决问题,但对外面的使用增加了复杂度-----需要setSleepTime()
-----------------------代码见后面
5. 更好的修改方法
5.1. 让Thread体面的结束
-----------------对于这里要emit的,可以放到thread的finished信号中,确保该线程结束后再emit,触发下一次执行,这样后面不需要setSleepTime
5.2. 增加锁以及完整的进程状态判定,不能仅通过标识位来判断
----------------参考上面
5.2.1. 锁、autointer方式保证这个更新,所有地方的缓存一致更新
5.2.2. 在finished里面做完所有事情,再将标识位清空-----如果用标识位的话(建议用enum的状态,而不是标识位)