in reply to Re: Sharing Tk-module objects in threads
in thread Sharing Tk-module objects in threads

It doesn't make much sense to try and run Tk in multiple threads, you (generally) only have one screen and only want one interface. Besides which, it's totally unnecessary.

Using one thread to maintain the user interface, and using one or more other threads do do your processing, and only communicating that information between them is such a natural split of responsibilities (shades of MVC). And, it's very simple to code.

It is so much easier to write your processing code as a single, "normal", top-to-bottom flow, than trying to split all your algorithms into iddy-biddy chunks that can be processed in under 1/10th of a second so as not to render the UI unresponsive.

All the fears of synchronisation problems using threads are completely unfounded. In fact, trying to coordinate and synchronise all those iddy-biddy bits of code through a state machine and global variables is infinitely harder, and vastly more fragile.

Breaking up processing into 1/10th second chunks is a real suck-it-and-see process to get right. And just when you have, the range of the values being processed changes, or the calculations you perform take slightly longer, and all the careful balancing of callbacks goes out the window.

Run your carefully balanced--UI responsiveness -v- maximal processing throughput--event-driven callback code on a processor that is slower than the development machines and the UI responsiveness drops.

Run it on a faster machine and you fail to get full benefit from that faster processor because your now serviceing the UI many times more frequently than necessary. Coding your Events and callbacks to dynamically account for processor speed and processor load is total nightmare. Been there, done that. Never again!

Trying do real work in between servicing User Interface Events is stupid. If you've ever worked in an office with a publicised telephone number and tried to get real work down between answering:

you'll understand this.

Have a one or two people dedicated to interfacing with the users, who field and filter every call, and then pass over the real problems--and concise, filtered information--to specialists.

One interface thread; one or more specialist worker threads; with just the minimum of required information being passed between them through some simple, reliable mechanism like Thread::Queue (or pipes or sockets).

Loosely coupled, simple and effective.

It's the same "loose coupling" philosophy that is (should be) foremost when designing OO code. Or, keeping Perl and HTML seperate.

I don't know who Slaven Reszic is--I can guess and I could find out--but provided people learn to only use Tk (or any other objects) from within a single process, there is no (logical) reason why Tk and iThreads shouldn't be used together.


Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"Think for yourself!" - Abigail
"Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
  • Comment on Re^2: Sharing Tk-module objects in threads

Replies are listed 'Best First'.
Re^3: Sharing Tk-module objects in threads
by zentara (Cardinal) on Nov 05, 2004 at 16:35 UTC
    Sorry, that should be Slaven Rezic, he's probably the #2 guy in Tk behind Nick Ing-Simmons, and the expert on comp.lang.perl.tk. He's also a monk here, I believe named esserte.

    I agree with you that threads can be used with Tk, but I've also seen threaded programs which seem to run fine, blow up for no reason every 100th run.


    I'm not really a human, but I play one on earth. flash japh
      but I've also seen threaded programs which seem to run fine, blow up for no reason every 100th run

      So have I, I wrote many of them.

      But I've also seen the mess (and created more than a few) when trying to code naturally monolithic algorithms to fit in with a global-state driven, event/callback system. Of the two, I find that latter is much harder to debug. With a threaded mechanism, you can code the processing algorithm as a stand-alone, single threaded piece of code and get that right--then just throw it in a thread. If the algoritm fails, you have a problem in your threading/locking/synchro code to fix. You know where the problem lies.

      With the state machine approach, you cannot test the monolithic part of the algorithm in isolation of the event driven part. Hence, your never quite sure in which part of the code the problem lies.

      With threads, the usual problem is incorrectly protected access to shared variables or incorrectly done semaphoring. I avoid both possibilities by only sharing data through a tried (and by me, trusted) mechanism of Thread::Queue. I've yet to see it fail (since 5.8.4).

      The two biggest problems with iThreads (IMO) are:

      1. The synchronisation, locking and semaphoring APIs are simple wrappers around the broken pthreads APIs. The cond_* functions are too low level, too complicated and messy for general use. IMO they are broken at the design level and should be replaced.
      2. The absence of thread prioritisation; suspend; resume; & kill function at the API level makes many things considerably more complicated than they should. It forces the user to hand implement stuff that should be a fundemental and integral part of any threading api.

      That lack, in the pthreads API which iThreads are based around, makes iThreads less useful than they could be, but that does not mean that they aren't useful at all. Used within their limitations, they can greatly simplify some types of processing.

      Event/callback apis are also useful for certain types of algorithm, especially those involving external interupts like UIs; but trying to force fit all your code to function in that manner is just painful.

      Most effective is a combination of the two. Event driven to process asynchronous events; Normal procedural or OO coding for end-to-end stuff; and threads to allow the two to happily co-exist within the same process.

      iThreads achieves this for the most part. The co-existance would be just that bit easier if there where ways of prioritising/suspending/resuming/terminating processing threads from the event driven code.


      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "Think for yourself!" - Abigail
      "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
        I always wondered why you always use Threads::Queue, :-) Now I know. Thanks for the nice summary.

        I'm not really a human, but I play one on earth. flash japh