http://qs321.pair.com?node_id=741725


in reply to Gtk2 app -- what's better, threads, or multiple timeouts?

I have had such great success using timeouts and events with Gtk2 that I have not bothered with threads. If you are experiencing lag, then either 1) run the main loop occasionally during cpu-intensive functions, 2) shorten the timeout time, or 3) allow other events (e.g. data ready on a pipe) to cause a different function to run.

I did a many-thousand line system this way and it ran very smoothly. For me the trick was when to allow timeouts and when to block them due to shared resources/data structures. In my case, I seldom used actual timeouts for swithching between functions. I wrote subs that ran for a very short amount of time that were triggered by internal or external events. The timers mostly served to cause screen synchronization with actual data, update the status of other nodes (in a cluster) and prevent the system from hanging when, say, an expected event such as a user input took some time.

One interesting thing to consider: if you are displaying a large amount of data, consider how often it must be updated and only compute values when they need to be displayed. That is, if you ahve a rapidly changing value for $foo, don't compute the median $foo until you need to show it (unless, of course, you need to do something else with it). This saves time and hence makes the system more responsive.

HTH,
--traveler

  • Comment on Re: Gtk2 app -- what's better, threads, or multiple timeouts?

Replies are listed 'Best First'.
Re^2: Gtk2 app -- what's better, threads, or multiple timeouts?
by ttlgreen (Sexton) on Feb 05, 2009 at 23:15 UTC
    If you are experiencing lag, then either 1) run the main loop occasionally during cpu-intensive functions

    Okay I'm not sure I understand this. I was under the impression that the main loop was always running. Does this mean that when I run a timeout, the main loop "waits" for whatever the timeout does to finish before it continues on? Observing my program it does seem like that is the case.

    Each run of the timeout in my program polls a certain website for changes, parses the new data (if any) and if there's something new it displays the data in the gui. So each run of the timeout has to wait for the webpage to be fetched which is where the slowdown is coming from.

    If I'm understanding how the main loop works, I think I'd like to have the main loop not wait for anything the program does in the background, but again I'm not sure if that's the right way to solve the problem. (Update: I should clarify that what I mean by "anything the program does in the background" is anything like the polling of the website that is not triggered by any gui events, it just does that all the time. In other words I want these background functions to be a seperate operation that doesn't effect the gui (unless there's something new to be displayed). Hopefully I'm making sense here ;-)

      The golden rule of event driven code is "never wait". Often that means that you need to initiate a process (start the fetch) then return and handle the reply some time in the future. One thing that implies is that you can only make non-blocking calls in the event processing.


      Perl's payment curve coincides with its learning curve.
      If you are experiencing lag, then either 1) run the main loop occasionally during cpu-intensive functions

      Okay I'm not sure I understand this. I was under the impression that the main loop was always running. Does this mean that when I run a timeout, the main loop "waits" for whatever the timeout does to finish before it continues on? Observing my program it does seem like that is the case.

      The main loop waits for events. When it gets one it processes it. If the event it is processing is a timer event tied to a sub of yours, it runs the sub. (Don't) try this

      while (1) { ... }
      It will hang the GUI. So in an event-driven environment such as Gtk2 you allow events to trigger subs. Never have your code sit around waiting for something to happen, that is the main loop's job. When something happens it will trigger an event (if you ask it to) and run your sub. The only time you should ask Gtk2 to process pending events if if you have a compute intensive block of code. For instance, if you are sorting a few zillion items, every once in a while (pun intended) try
      Gtk2->main_iteration while Gtk2->events_pending;
      This runs the main iteration code (which is what loops in the main loop while there are any events pending. Of course, you need to make sure that this does not mangle the data you are processing.