我正在做一个VoIP程序,它不断检查录音缓冲区中是否有任何内容(FMOD库,只要函数getRecordPosition> 0,然后缓冲区中就有数据)。
所以这将是:
while (true) {
if(getRecordPosition>0) {
process data....
}
}
然而,这会导致非常高的CPU使用率。一个版本是使用sleep()但是如果可能的话我宁愿不使用它。 例如,win32消息处理及其事件驱动的循环不会消耗很多cpu周期,这是我试图模仿的东西。同时我理解必须经常调用函数getRecordPosition()以查看返回值是否高于0.
为了保持低CPU使用率,我是否坚持做一段时间(真实)循环和睡眠()一段时间?
我用谷歌搜索并完成了一些查找,但大多数使用sleep()或某些POSIX与mutex同步返回。 (我正在做一个c ++ win32应用程序)
干杯
---编辑:忘记提及我无法访问fmod source corde:/ ---
答案 0 :(得分:5)
如果可以的话,最好的办法就是不要像你说的那样模仿事件驱动的架构,而是实际使用事件驱动的架构。我对你的代码一无所知,特别是你是否能够控制录音缓冲区的代码。但是如果你确实控制了写入缓冲区的代码,那么你可以在写入缓冲区时触发事件:
(psudocude如下)
HANDLE buf_event = CreateEvent(...);
// ...
CreateThread(BufferControl, ...);
OnWriteToBuffer()
{
buffer.Write(...);
SetEvent(buf_event);
}
然后在线程中,当缓冲区中的数据等待时,您想要执行某些操作,等待事件发出信号:
rc = WaitForSingleObject(buf_event, INFINITE);
if( rc == WAIT_OBJECT_0 )
{
// there's somethign in the buffer
}
答案 1 :(得分:1)
您可以使用'SwitchToThread'将处理器转换为另一个线程,并检查返回值。如果是,那么你就屈服了,如果没有,就没有其他线程需要运行。如果我没记错的话,FMOD会运行一个线程,所以你可能会屈服于那个线程。
如果它无法产生或者它继续消耗大量的CPU时间,你可以使用屈服和睡眠的某种组合。
答案 2 :(得分:1)
我不熟悉FMOD库,但它是否提供了数据放入缓冲区时的通知回调?如果没有,你几乎停留在使用某种形式的睡眠(你可以把这些代码放在一个线程中并使用类似nanosleep的东西来保持良好的响应时间)。
答案 3 :(得分:0)
我们遇到了类似的问题 我们有许多进程试图共享资源。在其中一个持有该资源之后,另一个应该等待该资源可用。这意味着,等待一段时间,而不是试图锁定资源,如果不可用,再次休眠 由于我们必须在Windows和Linux上开发该代码,我们面临着不同的解决方案,即使使用boost(但没有有效的结果)。 无论如何,Windows中的最佳解决方案是在资源上使用WaitForSingleObject(),但在linux上我们只需要睡眠1毫秒。该解决方案似乎消耗了非常低的CPU - 而不是一段时间(真实) - 授予资源尽快获取。
一开始,我们在资源可用性测试和以下之间休息了很多时间,因为我们睡了很多毫秒。现在我们实际上非常快。 HTH
答案 4 :(得分:0)
考虑Win32必须提供的其他同步原语。自动重置事件听起来就像您需要的那样。他们也在进行交叉处理。
答案 5 :(得分:0)
为了避免消耗CPU并避免Sleep()函数的低效率,您需要避免轮询,而是使用事件驱动机制。有一些现成的框架。例如,在GBL中,您将定义一个信号,比如getRecordPosition,并将其绑定到处理程序:
Handler([](){ do_something(); }) << getRecordPosition;
或者如果你需要一个单独的线程,你会等待信号:
CreateThread([](){ Wait(getRecordPosition); do_something(); });