Loop without consuming too many CPU cycles and without sleep()?
I am doing a VoIP program which continously checks whether the audio-recording buffer has anything in it (FMOD library, whenever the function getRecordPosition > 0, then the buffer has data in it).
So it would be something along the lines of:
while (true) {
if(getRecordPosition>0) {
process data....
}
}
However开发者_如何学Python this would cause a very high CPU usage. One version would be to use sleep() but I'd rather not use it if possible. For example the win32 messagehandling with its event-driven loop dosn't consume many cpu cycles and it's something I'm trying to emulate. At the same time I understand the function getRecordPosition() would have to be called frequently to see if the return value gets above 0.
Am I stuck with doing a while(true) loop and sleep() for some small amount of time in order to keep low-CPU usage?
I've googled and done some lookup but most returns either using sleep() or some POSIX synchronization with mutex. (I am doing a c++ win32 app)
Cheers
---EDIT: Forgot to mention I dont have access to fmod source corde :/ ---
The best thing to do, if you can, is to not emulate an event-driven architecture as you say, but to actually use an event-driven architecture. I don't know anything about your code, in particular whether you're in control of the audio-recording buffer's code or not. But if you do control the code that writes to the buffer, then you can trigger an event when you have written to the buffer:
(psudocude follows)
Main Thread:
HANDLE buf_event = CreateEvent(...);
// ...
CreateThread(BufferControl, ...);
Buffer-Write Thread:
OnWriteToBuffer()
{
buffer.Write(...);
SetEvent(buf_event);
}
And then in the thread where you want to do something when there's data in the buffer waiting, wait for the event to be signaled:
Buffer-Read Thread
rc = WaitForSingleObject(buf_event, INFINITE);
if( rc == WAIT_OBJECT_0 )
{
// there's somethign in the buffer
}
You could use 'SwitchToThread' to yield the processor to another thread, and check the return value. If it is true, you yielded, and if not, there are no other threads that need running. If I remember correctly, FMOD runs a thread, so you would likely be yielding to that thread.
If it fails to yield or if it continues to use up a lot of CPU time, you could use some combination of yielding and sleeping.
I'm not familiar with the FMOD library, but does it provide a notification callback for when data is placed in the buffer? If not, you're pretty much stuck using some form of sleep (you could put that code in a thread and use something like nanosleep to still have good response times though).
We faced a similar problem.
We have many processes trying to share a resource. After one of those held that resource, the other should wait for that resource to be available. That means, wait a while, than try to lock the resource and, if not available, sleep again.
Since we have to develop that code both on Windows and Linux we faced different solutions, even using boost (but wit no valid results).
Anyway, best solution in Windows was to use a WaitForSingleObject() on the resource, but on linux we had to sleep for just 1 millisecond. That solution seems to consume very low CPU - instead of a while(true) - granting the resource to be taken as soon as available.
In the beginning we were loosing much time sleeping between a test of resource availability and the following since we sleep for to many milliseconds. Now we're actually very faster. HTH
Consider other sync primitives that Win32 has to offer. An auto-reset event sounds like what you need. They work cross-process, too.
In order to avoid consuming CPU and avoid inefficiency of Sleep() function, you need to avoid polling, instead use event driven mechanism. There are ready frameworks for that. For example, in GBL, you would define a signal, say getRecordPosition, and bind it to handler:
Handler([](){ do_something(); }) << getRecordPosition;
or if you need a separate thread, you would wait for the signal:
CreateThread([](){ Wait(getRecordPosition); do_something(); });
精彩评论