Glen Holcomb
7/24/2008 12:55:00 PM
[Note: parts of this message were removed to make it a legal post.]
On Thu, Jul 24, 2008 at 2:24 AM, Alex Fenton <alex@deleteme.pressure.to>
wrote:
> Glen Holcomb wrote:
>
> I have a small GUI app that I have written the purposes for it's creation
>> are two-fold and irrelevant. Here is my problem:
>>
>> I have two threads aside from the main thread. One that wakes machines at
>> scheduled times and another that shuts them down at scheduled times.
>> Unfortunately Ruby's scheduler seems to care less when a thread actually
>> wakes up as long as it doesn't wake up early. Sometimes I have a five
>> minute (wall time) gap between when the thread should wake and when it
>> actually does.
>>
>> The observed behavior seems to be magnified/caused by minimizing the
>> application. Does anyone have any suggestions that could lead to a more
>> responsive app? 5+ minutes late wouldn't matter so much if it didn't
>> cause
>> the thread to miss an event scheduled a minute or two after the one that
>> was
>> late. I suppose I could re-structure my code and may have to. I was just
>> hoping that there is a way to get tolerable responsiveness out of a
>> thread.
>>
>
> Most of the GUI libraries for Ruby are based on C/C++ and while a GUI app
> is running spend most of the time in an "event loop" - a bit of native code
> which waits for user actions. As I understand it, ruby's thread scheduler
> won't switch thread context whilst native extension code - eg the event loop
> - is executing. So non-GUI ruby (green) threads can get starved of execution
> time.
>
> There are two possible solutions to this, the exact implementation of which
> will depend on the toolkit. Both depend on using the timing/regular event
> facilities provided by GUI toolkits, which will be respected by the event
> loop - I've seen discussion relating to different libraries. I'll use Wx as
> an example.
>
> One is to regularly schedule time for the non-GUI threads, using Ruby's
> Thread.pass. In wxRuby:
>
> Wx::Timer.every(50) { Thread.pass }
>
> This sets a Timer which will wake and run the subordinate threads every
> 50ms.
>
> The other way is to dispense with Ruby's thread's altogether and just use a
> timer. This may be more suitable for your use case:
>
> Wx::Timer.after(5000) { DO SHUTDOWN ACTION... }
>
> hth
> alex
>
>
>
Thanks for the tip Alex. I'll definitely look into it. I'm using Wx so
your example is perfect ;) I've never done any GUI programming so part of
this experiment was to learn the nuances and at least one framework which I
appear to be doing.
To answer your question Pit I'm running this in Windows XP. I haven't had
problems with any of my other scripts either although this is the first
threaded code I've written in Ruby.
--
"Hey brother Christian with your high and mighty errand, Your actions speak
so loud, I can't hear a word you're saying."
-Greg Graffin (Bad Religion)