简体   繁体   English

同步循环线程

[英]Synchronizing looping threads

I am making some multi-threaded video game code. 我正在制作一些多线程视频游戏代码。 Before I began coding I looked at an article describing vaguely Valve's solution to multi-threaded game design. 在开始编码之前,我看过一篇文章,模糊地描述了Valve的多线程游戏设计解决方案。 A key concept I gleaned from the article is thread synchronization. 我从本文中学到的一个关键概念是线程同步。 I don't know if this is how Valve does it but I imagined multiple threads each executing a game loop. 我不知道这是否是Valve的工作方式,但我想像有多个线程各自执行一个游戏循环。 At the end of each iteration, the threads pause and wait for other threads to finish their current iteration, then synchronize shared data. 在每次迭代结束时,线程暂停并等待其他线程完成其当前迭​​代,然后同步共享数据。 I figure that besides the overhead is this management scheme, there would be no different to just let the threads operate completely asynchronously. 我认为,除了开销是这种管理方案外,让线程完全异步运行也没有什么不同。 The article mentioned a thread used exclusively for syncing but I am trying to get a different solution to work correctly. 文章提到了专门用于同步的线程,但我正在尝试获取其他解决方案以使其正常工作。 This is how I (try) to do it: 这是我(尝试)的方法:

        // at end of loop on each thread...
        sig_thread_done();

        while (!is_sync_done())
        {
            PauseExecution(1);
        }

sig_thread_done and is_sync_done are function objects from another class that controls a list of all "threads". sig_thread_done和is_sync_done是另一个类的函数对象,该类控制所有“线程”的列表。 These functions look like this: 这些函数如下所示:

bool Core::IsFrameDone()
{
    MutexLock lock(manager_mutex);

    if (waiting_components == -1)
    {
        waiting_components = 0;
        return true;
    }
    return false;
}

void Core::SignalFrameDone()
{
    MutexLock lock(manager_mutex);

    if (++waiting_components == (int)components.size()) // components == threads
    {
        //sync shared data...
        waiting_components = -1; // -1 signifies that all threads have completed their iteration
    }
}

The problem is that a fast thread can exit its waiting loop and come back around to it again before other threads have a chance to exit there's. 问题在于,快速线程可以退出其等待循环,然后在其他线程有机会退出该循环之前再次回到该循环。 So the other threads miss the exit through is_sync_done returning false before another thread begins waiting and the whole system gets stuck waiting forever. 因此,其他线程错过了退出,因为is_sync_done在另一个线程开始等待之前返回false,从而整个系统陷入永远等待。

I can't find an easy way to resolve this issue. 我找不到解决此问题的简便方法。 I really like this approach because synchronization doesn't get stalled while some independent thread performs the sync. 我真的很喜欢这种方法,因为在某些独立线程执行同步时同步不会停止。

I appreciate any insight or suggestions anyone has to offer. 我感谢任何人提供的任何见解或建议。

Link to article. 链接到文章。

我认为您正在尝试重新发明Thread barrier

For something like this you want to sync on a barrier, with something like a Win32 Event (or an array thereof), this makes sure you cannot get the situation you described (the barrier ensures that everything syncs up to the same frame ) while at the same time freeing CPU time, as waiting on events is done as a kernel signal, and sleeps the thread till that signal is received. 对于这样的事情,您想在屏障上与Win32事件(或其数组)进行同步,这可以确保您无法获得所描述的情况(屏障确保所有内容都同步到同一 ),而在在释放CPU时间的同时,等待事件作为内核信号完成,并使线程休眠直到接收到该信号。 You'd also what to use wait-free algorithms in there, these work particularly well if you have a job/task based threading model, where certain things can be decoupled from the system. 您还可以在那里使用免等待算法,如果您有一个基于作业/任务的线程模型,可以将某些事情与系统分离,那么这些算法特别有用。

Also, here is a better publication on multi-threading the source engine, its far more in depth and technical (they also specifically state that they avoid mutexes for this sort of thing). 另外, 是一本关于多线程源引擎的更好的出版物,它在深度和技术上要深入得多(他们还特别声明他们避免这种情况下使用互斥体)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM