#173841 - 05/08/2003 10:49
Off-topic programming question
|
carpal tunnel
Registered: 20/12/1999
Posts: 31602
Loc: Seattle, WA
|
This is about programming, but it's about VB programming instead of empeg programming. But since it's about the EmpegFace program I'm trying to get working properly, I think it's OK to post it here.
The question: How to get a proper "relax and let things go" loop written that doesn't appear to consume 99% CPU in Task Manager when it's idle.
The standard thing in VB is to put the DoEvents statement in your loop. This allows messages to get processed by other programs (and elsewhere in your own program) whenever needed, yet allows your loop to continue. This works fine, doesn't slow down other programs, and still leaves your program responsive within the loop.
Except that when your program is idle and looping, and nothing else is doing anything important on the system, then Task Manager shows your idle loop consuming 99 percent CPU time, instead of the system idle process doing it. This produces complaints from your users.
The other way around this is to re-architect your program so that it doesn't need the idle loop. For example, using a timer to do the idling. Let's assume for a moment that I can't do this for various reasons. I'm already using timers for some things and in this particular case I've got my reasons for not wanting to use a timer.
Googling for solutions gives me replacement idle loops which call the Windows API functions GetMessage or PeekMessage. These work, but there is a problem: When I use the PeekMessage alternatives, the result is exactly the same as DoEvents: Idle loops consume 99 percent CPU time (in fact I think this behavior is an indication that DoEvents really is just a PeekMessage loop under the hood). When I use the GetMessage alternative, my program sits there and locks up waiting for a message (since in my idle loop, I'm not getting any messages, and the GetMessage alternatives only perform an action when there is a message to get).
Anyone got any ideas, or can you point me to any example code variations that use GetMessage and/or PeekMessage in ways that are satisfactory?
|
Top
|
|
|
|
#173842 - 05/08/2003 11:12
Re: Off-topic programming question
[Re: tfabris]
|
carpal tunnel
Registered: 14/01/2002
Posts: 2858
Loc: Atlanta, GA
|
I always do any idle looping with timers, for the specific reasons you've outlined. Since you'd like (or need) to do this in a different way, what is the purpose of the idle loop? Are you waiting for a signal? I haven't coded in VB before, but I assume that most of the API calls I have available in Delphi (and therefore techniques) will also be available to you.
_________________________
-Jeff Rome did not create a great empire by having meetings; they did it by killing all those who opposed them.
|
Top
|
|
|
|
#173843 - 05/08/2003 11:16
Re: Off-topic programming question
[Re: JeffS]
|
carpal tunnel
Registered: 20/12/1999
Posts: 31602
Loc: Seattle, WA
|
The timers in VB have a lower limit to their resolution, and I'd like to be able to do the loop more frequently than they allow, yet still not consume all the CPU to do it.
|
Top
|
|
|
|
#173844 - 05/08/2003 11:30
Re: Off-topic programming question
[Re: tfabris]
|
carpal tunnel
Registered: 24/12/2001
Posts: 5528
|
Is there no yield function?
There's a big article on MSDN here about PeekMessage/GetMessage
|
Top
|
|
|
|
#173845 - 05/08/2003 11:31
Re: Off-topic programming question
[Re: tfabris]
|
carpal tunnel
Registered: 14/01/2002
Posts: 2858
Loc: Atlanta, GA
|
Are you polling to try and respond to an external windows message, or is this something that you're generating internally (or are you not polling at all and I'm missing the point)?
_________________________
-Jeff Rome did not create a great empire by having meetings; they did it by killing all those who opposed them.
|
Top
|
|
|
|
#173846 - 05/08/2003 11:42
Re: Off-topic programming question
[Re: JeffS]
|
carpal tunnel
Registered: 20/12/1999
Posts: 31602
Loc: Seattle, WA
|
(or are you not polling at all and I'm missing the point)? I'm trying to find a way for the program to sit and wait for something to change that doesn't involve windows messages at all. The only reason I'm trying Peek/Get is because examples on the 'net said "hey, this is an alternative to a DoEvents idle loop".
/me heads off to look at the linked MSDN article.
|
Top
|
|
|
|
#173847 - 05/08/2003 11:52
Re: Off-topic programming question
[Re: tfabris]
|
carpal tunnel
Registered: 14/01/2002
Posts: 2858
Loc: Atlanta, GA
|
I'm probably being unhelpful here, so ignore whatever doesn't make sense to your problem. However, in Delphi you can simply declare new message events and they get triggered whenever you do a "post message", no loop needed. Underneath it all (I know because I've looked) it's really just registering these events with windows when it creates the main application window. I can only assume that there's a way to do this in VB. This would allow you to respond when something changes through windows messaging.
The "atomic bomb" approach is that you could spawn a separate thread that does a CPU-friendly wait and then executes as soon as you trip it through with event. Of course then you have to take steps to ensure that you are synchronizing everything properly with the main thread so you don't start causing multi-threading issues. Probably too much for what you're wanting, and I'm not sure how hard multi-threading is to do in VB. However, it's very CPU friendly to do this in order to wait on something specific that either trips an event or you can cause to trip an event..
_________________________
-Jeff Rome did not create a great empire by having meetings; they did it by killing all those who opposed them.
|
Top
|
|
|
|
#173848 - 05/08/2003 11:54
Re: Off-topic programming question
[Re: JeffS]
|
carpal tunnel
Registered: 20/12/1999
Posts: 31602
Loc: Seattle, WA
|
If it weren't such a pain to do multi-threading in VB, I'd definitely take that approach. In fact, the whole presence of this idle loop is a work-around to the fact that VB multithreading is a PITA.
|
Top
|
|
|
|
#173849 - 05/08/2003 12:20
Re: Off-topic programming question
[Re: tfabris]
|
carpal tunnel
Registered: 20/12/1999
Posts: 31602
Loc: Seattle, WA
|
Hmm. I seem to have worked around it for now, and I'm going to see if this works out long term. For now, the answer to my original question is now an academic curiosity. The MSDN article sheds a lot of light on the subject, thanks for that link.
|
Top
|
|
|
|
#173850 - 05/08/2003 12:21
Re: Off-topic programming question
[Re: tfabris]
|
carpal tunnel
Registered: 18/01/2000
Posts: 5683
Loc: London, UK
|
I think this behavior is an indication that DoEvents really is just a PeekMessage loop under the hood
IIRC, it is.
What is it that you're waiting for? This might give us some clues about other ways to wait for it.
_________________________
-- roger
|
Top
|
|
|
|
#173851 - 05/08/2003 12:25
Re: Off-topic programming question
[Re: Roger]
|
carpal tunnel
Registered: 20/12/1999
Posts: 31602
Loc: Seattle, WA
|
I'm embarassed to say. It's a really kludgy work around to the lack of easy multithreading code in VB.
Anyway, like I said, I think it's working OK now and I no longer need the alternative to the idle loop.
|
Top
|
|
|
|
#173852 - 05/08/2003 12:32
Re: Off-topic programming question
[Re: tfabris]
|
carpal tunnel
Registered: 14/01/2002
Posts: 2858
Loc: Atlanta, GA
|
Glad you found something that works. Just for the sake of posting what I've found, it seems you can handle windows messages in VB with AddressOf, which I believe would enable you to put whatever it is you're waiting for into the main message handler, if I understand everything correctly (which I may not, as I just skimmed the page). Then you wouldn't have to poll for anything and only respond when the event happens.
_________________________
-Jeff Rome did not create a great empire by having meetings; they did it by killing all those who opposed them.
|
Top
|
|
|
|
#173853 - 05/08/2003 12:43
Re: Off-topic programming question
[Re: JeffS]
|
carpal tunnel
Registered: 20/12/1999
Posts: 31602
Loc: Seattle, WA
|
Ooo, that's neat. I'll hang onto that one for future reference.
|
Top
|
|
|
|
#173854 - 05/08/2003 13:20
Re: Off-topic programming question
[Re: tfabris]
|
journeyman
Registered: 14/03/2002
Posts: 94
Loc: Pennsylvania
|
The question: How to get a proper "relax and let things go" loop written that doesn't appear to consume 99% CPU in Task Manager when it's idle. Use the API command Sleep together with Doevents.
Put this in a module: Public Declare Sub Sleep Lib "kernel32" Alias "Sleep" (ByVal dwMilliseconds As Long) Then you can make a loop like this: Do
Sleep 1
DoEvents
Loop This gives execution back to windows for 1 millisecond, then returns to your program to do a DoEvents command. Task manager will show your program as using 0% cpu.
|
Top
|
|
|
|
#173855 - 05/08/2003 15:21
Re: Off-topic programming question
[Re: DomoKun]
|
carpal tunnel
Registered: 20/12/1999
Posts: 31602
Loc: Seattle, WA
|
I could swear I tried this and for some reason it didn't work. Don't remember why, but I remember giving up on the Sleep API pretty quickly. If I have to go back to the loop method again, though, I'll make sure to try it exactly as you just showed. Perhaps I wasn't doing it exactly that way.
|
Top
|
|
|
|
|
|