You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Apr 17, 2024. It is now read-only.
根据最新的一次 PR #106 ,目前存在一些问题。问题参见该 PR 的评论 #106 (comment) 、#106 (comment)与 #106 (comment)。
先假设仍然使用
mtx_state
和mtx_buffer
(后面会看到mtx_state
时没有必要使用的)。其中,mtx_state
用于锁pState
,mtx_buffer
用于锁pBuffer
。设计思路分两种讨论:
在一次
play
调用期间不改变如果要在一次
play
调用期间选手获取到的信息不改变,则采用如下设计:LoadBuffer
负责当信息到来时更新pBuffer
,使用bool bufferDirty
标记其更新过 buffer,并唤醒条件变量bufferCond
:Update
用于交换pBuffer
和pState
要使一次循环中信息不改变,则交替执行
Update
和 AI 代码即可:注意到,如果在一次调用期间获取的信息不改变,那么,
pState
只会有一个线程在使用(即 AI 代码的线程),因此在一般情况下可以不使用mtx_state
锁(如果选手自己开多线程,并且在play
返回之后子线程没有退出,则可能会出现并发问题,不过我们不妨将此视为选手的非法操作 x)。在一次
play
调用期间改变这种情况真的想了很久,非常诡异,怎么写都觉得有些不舒服,姑且贴几种可选的做法吧:
这种情况就必须要使用两个锁了,因为将看到,对
pState
的读和写使用不同的线程;此外这种情况必须为选手提供Wait
接口用于等待下一帧的到来;取消Update
函数方法一
使用条件变量
frameCond
实现Wait
Wait
并没有等到下一帧到来便被唤醒。目前我不知道虚假唤醒的影响有多大。方法二
使用一个标志变量
std::atomic_bool freshed
防范虚假唤醒。Wait
的情况。如果选手开了多个线程Wait
,则可能导致一些线程将freshed
置为false
而导致其他的线程唤醒失败方法三
每一帧赋予一个
freshed
变量,即可解决上述问题lock free
的,也有较大开销The text was updated successfully, but these errors were encountered: