【发布时间】:2021-08-26 05:48:39
【问题描述】:
我正在尝试创建一个简洁高效的设计,将事件传递给后台线程进行评估,然后将选定的结果返回给游戏线程。
这是我最初的设计
//Occurrence object passed from director on game thread to background thread OccurrenceQueue
//Execute BackgroundThread::EvaluateQueues()
//If OccurrenceQueue.Dequeue()
//Score Occurrence, then return via Occurrence.GetOwner()->PurposeSelected(Occurrence)
//EvaluateQueues()
这导致了从事件中选择一系列目的的干净循环。所以现在我想把它移到后台线程。以下是我到目前为止所学到的:
-
线程安全(在 UE 中)绝对不需要修改 UObject 来自其他线程的数据(根据我的阅读,这是由于他们的自定义 GC)
- 您可以锁定对象和/或设计,以便背景中的对象
线程没有被游戏线程触及,但仍有风险
由于背景未延长寿命而导致的意外行为 线程和同步问题
- 您可以锁定对象和/或设计,以便背景中的对象
-
您不能简单地在游戏线程现有对象上执行函数 将调用栈移回游戏线程
-
调用 Occurrence.GetOwner()->PurposeSelected(Occurrence) 从 后台线程保留在后台线程中
- 这是我希望更好地理解的主要主题
-
这也适用于 UE 中的代表
-
-
UE 中的 TQueue 可以安全地跨线程使用
从我上面了解到的情况来看,我目前的设计似乎在逻辑上是不可能的。
到目前为止,这些是我的选择:
-
使用两个队列
-
一个在后台线程上出列和评分
-
另一个通过tick使游戏线程上的结果出队
-
-
使用游戏线程中存在的委托,通过tick调用OccurrenceEvaluated.Broadcast()
- 对结果进行评分时,将 Occurrence.GetOwner()->PurposeSelected(Occurrence) 绑定到 OccurrenceEvaluated
-
我已经看到 c++ 使用称为 Future() 的东西(或类似的东西)来执行异步任务,并且似乎 UE 与 TFuture && TFuture.IsReady() 有类似的东西,但我还没有深入研究了解它以及它如何返回数据
- 与 FAsyncTask 相同
我很犹豫是否要实现任何利用滴答检查数据是否已从后台线程更新/返回的设计。
任何人都可以建议相关的设计实践,或澄清从后台线程返回执行到主线程的性质(我很难找到正确的问题来研究/了解这方面的信息)?
【问题讨论】:
标签: c++ multithreading queue unreal-engine4