Reputation: 3135
I am writing two applications that work with each other. One is in c++, the other in C#. As there is streaming data involved, I am using, in multiple places, code such as:
while (true)
{
//copy streamed data to other places
}
I am noticing that these programmes use a lot of cpu, and become slow to respond. Is it bad programming to use this kind of loop? Should I be adding a:
Sleep(5);
In each one? Will that help with cpu usage?
Thanks!
Upvotes: 1
Views: 1589
Reputation: 21
What you really need to avoid (for the health of your CPU) is to make your program waiting for data in a while(true)
loop without using a system threading wait function.
Example 1:
while(true) {
if (thereIsSomeDataToStream) {
StreamDataFunction();
}
}
In this example, if thereIsSomeDataToStream
is false for a time, then CPU will still continue to work 100% performing while
loop even if there is no data to stream. So this would be waste of CPU and leads your computer to slow down.
Example 2:
while(true) {
if (thereIsSomeDataToStream) {
StreamDataFunction();
}
else {
SystemThreadingWaitFunction();
}
}
On the contrary, in this example, when there is no more data to stream, then the thread stops for a time. Operating system will use this free time to execute other threads and, after a while, system will wake up your thread which will resume and loop again for streaming possible new data. Then there is not too much waste of CPU and your computer will remain responsive.
To perform the thread waiting procedure, you may have several possibilities:
First, you can use, as you suggested, Sleep(t)
. This may do the
job: Sleep functions provided by compilers logically would use
operating system API to idle current thread. But in this case you
will have to wait all the specified time, even if some data came
meanwhile. So if waiting time is too short, CPU will overwork, and if
time is too long, your streaming will lag.
Or you can use operating system API directly, which I would
recommend. If you are using Microsoft environnement, there are lots
of waiting methods you can document on here: Microsoft wait
functions API. For example you can create an Event object which
will signal incoming data to stream. You can signal this event
anywhere in your code or from another program. In the while
loop you
may then call a function like WaitForSingleObject
API which will wait
the event for signal state. Here is documentation on how to do this:
Using event objects. I do not know about linux or other systems,
but I am sure you can find it on the web. I did it few times myself,
it is not so hard to code. Enjoy ! :)
Upvotes: 1
Reputation:
This is expanding on my comment above, but for the sake of completeness I am pasting what I've written in the commend here (and adding to it).
The general solution to this sort of problem is to wait for arrival of data and process it as it arrives (possibly caching newly arrived data as you're processing previously arrived data). As to the mechanics of the implementation - well, that depends on a concrete example. For example, often in a graphics processing application (games, for instance), the "game loop" is essentially what you describe (without sleeps). This is also encountered in GUI app design. For a design where the app waits for an event before processing, look to typical network client-server design.
As for the slowdown of the CPU, try the following code to observe significant slowdown:
while(true);
versus
while(true) sleep(1);
The reason the first slows down is because on each cycle the CPU checks if the condition in the loop evaluates to true
(that is, in this case, if true == true
). On the other hand, in the second example, the CPU checks if true == true
and then sleeps for 1ms
, which is significantly longer than the amount of time it takes to check true == true
, freeing the CPU to do other things.
Now, as for your example, presumably processing the data inside the loop takes significantly more CPU cycles than checking true == true
. So adding a sleep
statement will not help, but only worsen the situation.
You should leave it to the kernel to decide when to interrupt your process to dedicate CPU cycles to other things.
Of course, take what I wrote above with a grain of salt (especially the last paragraph), as it paints a very simplistic picture not taking into account your specific situation, which may benefit from one design versus another (I don't know, because you haven't provided any details).
Upvotes: 0
Reputation: 4733
Generally, using Thread.Sleep()
in the code will also freeze the thread so if what you worry about is responsiveness you shouldn't use it. You should consider moving the streaming methods out of the main (UI) thread
Also, you mentioned that it is some streaming process, so the best practise wouldn't be something like
while(!stream.EndOfStream)
{
//streaming
}
but rather using some DataReceived events (if available)
Upvotes: 5
Reputation: 3586
you will probably find that the code is more of the format
while (true)
{
//WAIT for streamed data to arrive
//READ data from stream
//COPY streamed data to other places
//BREAK when no more data/program is ending
}
which is totally normal. the other common solution is
while (boolean_variable_if_program_is_to_keep_running)
{
//WAIT for streamed data to arrive
//READ data from stream
//COPY streamed data to other places
//when no more data/program is ending
// set boolean_variable_if_program_is_to_keep_running = FALSE
}
Upvotes: 2