我正在创建一个简单的2D游戏引擎,我想在不同的线程中更新和渲染精灵,以了解其完成方式。
我需要同步更新线程和渲染线程。当前,我使用两个原子标志。工作流程如下所示:
Thread 1 -------------------------- Thread 2
Update obj ------------------------ wait for swap
Create queue ---------------------- render the queue
Wait for render ------------------- notify render done
Swap render queues ---------------- notify swap done
在此设置中,我将渲染线程的FPS限制为更新线程的FPS。此外,我sleep()
经常将渲染和更新线程的FPS限制为60,因此这两个等待函数不会等待太多时间。
问题是:
平均CPU使用率约为0.1%。有时,在四核PC中,它会上升25%。这意味着一个线程正在等待另一个线程,因为wait函数是一个带有test and set函数的while循环,而while循环将使用您的所有CPU资源。
我的第一个问题是:是否有另一种方式同步两个线程?我注意到std::mutex::lock
在等待锁定资源时不要使用CPU,因此它不是while循环。它是如何工作的?我无法使用,std::mutex
因为我需要将它们锁定在一个线程中并在另一个线程中解锁。
另一个问题是;由于该程序始终以60 FPS的速度运行,为什么有时它的CPU使用率会跃升到25%,这意味着两个等待中的一个正在等待很多?(两个线程都限制为60fps,因此理想情况下它们不需要太多同步)。
编辑:感谢所有答复。首先,我想说的是,我不会在每个帧开始渲染新线程。我从一开始就开始了update和render循环。我认为多线程可以节省一些时间:我具有以下功能:FastAlg()和Alg()。Alg()既是我的Update obj又是render obj,而Fastalg()是我的“发送渲染队列到” renderer”“。在一个线程中:
Alg() //update
FastAgl()
Alg() //render
在两个线程中:
Alg() //update while Alg() //render last frame
FastAlg()
因此,也许多线程可以节省相同的时间。(实际上,在简单的数学应用程序中,它确实是这样,其中alg是一个长算法,而fastalg是一个更快的算法)
我知道睡觉不是一个好主意,尽管我从来没有遇到过问题。这样会更好吗?
While(true)
{
If(timer.gettimefromlastcall() >= 1/fps)
Do_update()
}
但这将是一个无限的while循环,它将使用所有CPU。我可以使用sleep(数字<15)来限制使用吗?这样,它将以例如100 fps的速度运行,并且更新功能每秒仅被调用60次。
为了同步两个线程,我将使用带有createSemaphore的waitforsingleobject,以便能够在不同的线程中锁定和解锁(使用while循环进行淘汰),不是吗?