多线程的奇怪结结巴巴问题

本文关键字:结结巴巴 问题 多线程 | 更新日期: 2023-09-27 17:57:34

我修改了上一篇文章中的物理:在单独的线程中更新物理引擎,这明智吗?像这样:

public void PhysicsThread()
{
    int milliseconds = TimeSpan.FromTicks(333333).Milliseconds;
    while(true)
    {
        System.Threading.Thread.Sleep(milliseconds);
        world.Step(milliseconds / 1000.0f);
    }
}

和以前一样,它在自己的线程中运行。我发现了一些奇怪的东西,我不确定我是否完全理解,这有点难以解释,所以我录了一段视频:http://www.youtube.com/watch?v=qFf6oSRfVt8

如果你仔细观察,你可以看到从大炮发射的物体偶尔会结巴,并似乎向后移动了一段距离。这仅在快速移动的物体(如发射的炮弹)上可注意到。

这完全让我感到困惑。我甚至创建了一个系统,在这个系统中,我缓存了游戏逻辑线程中实体的位置,这样当物理线程可以更新实体位置时,它不会影响游戏逻辑读取的位置,直到在游戏逻辑线程内调用更新函数,更新物理实体位置以供游戏逻辑读取。

你知道多线程的哪个方面可能导致了这个问题吗?我不认为是物理引擎在游戏逻辑和绘图过程中更新身体位置,正如我已经提到的那样,我缓存了它,并且它在整个过程中保持不变。。。

多线程的奇怪结结巴巴问题

我的第一个猜测是,您可能有一个经典的竞争条件,即多个线程在没有锁定或排序保证的情况下竞争更新对象的位置。

您可以查看维基百科来了解更多关于竞争条件、锁定和其他多线程/多处理基础知识的信息。

如果不看到更多的代码,尤其是进行更新的部分,很难说得更多。

编辑:您可以做的一件事是存储DateTime。现在在每个循环中,将其与以前的值进行比较。如果你的时间延迟不一致,你会看到的。

另一件需要检查的事情是看看你的世界有多长。Step()函数正在执行(再次使用DateTime.Now和一些日志记录,或者其他什么)。

如果这两者都表明时间一致,那么我的怀疑将落在物理引擎上。在调用world之前和之后检查对象的位置。Step(),如果你看到任何奇怪的跳跃,它应该告诉你去哪里看。

这可能是一条注释,但发布代码会很困难。如果你尝试实时,那么这个代码很容易出现时间抖动,因为无法保证Thread.Sleep会在规定的时间内睡眠。我会用秒表来测量经过的时间,并用它来驱动你的世界。

public void PhysicsThread()
{
    int milliseconds = TimeSpan.FromTicks(333333).Milliseconds;
    var stopwatch=System.Diagnostics.Stopwatch.StartNew();
    while(true)
    {
        System.Threading.Thread.Sleep(milliseconds );
        world.Step(stopwatch.ElapsedTicks);
        stopwatch.Restart();
    }
}