in reply to Re^2: bidirectional pipe freezing
in thread bidirectional pipe freezing

Multi threading could be an answer, but Tk is not thread safe.

Tk isn't "thread-safe", but it does run perfectly safely in a single thread.

That is, you can have as many background threads running as you need in your TK app, provided that none of those other threads attempt to talk directly to the GUI.

The basic method is that you start all your background threads runnung before you require Tk and build your GUI. And you then use Thread::Queue(s) to send commands from the GUI to the worker threads and another to receive back results. It is a simple, efficient mechanism that avoids all the fuss and bother of buffered pipes or sockets and select loops.


With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

The start of some sanity?

Replies are listed 'Best First'.
Re^4: bidirectional pipe freezing
by chessgui (Scribe) on Dec 21, 2011 at 19:58 UTC
    @BrowserUk,

    thanks for your contribution. Your approach seems to be the most straightforward. It is simple and powerful. With this approach (at least on my platform) you don't even need require. You can go ahead and use Tk.

    Believe it or not, the following code works:
    use Tk; use threads; use Thread::Queue; my $q = Thread::Queue->new(); my $thr = threads->create(sub { ###################################################### # thread working on input received from Tk MainWindow do { my $item = $q->dequeue(); print "Received: $item\n"; } while(1); ###################################################### })->detach(); ###################################################### # here comes the Tk stuff $mw=new MainWindow; $mw->repeat(1000,\&handler); MainLoop; sub handler { $i++; $q->enqueue("command $i"); } ######################################################
      With this approach (at least on my platform) you don't even need require. You can go ahead and use Tk.

      Indeed, it works fine like that. The only downside is that your threads will 'inherit' various bits of Tk code and data that they cannot use.

      Whilst the additional memory consumed is insignificant unless you are really pushing the boundaries of your system, the fact that the Tk::* name space is visible within your threads can lead to the temptation to try and use it.

      What is worse is that sometimes, some calls will actually seem to work. Until they stop -- usually by crashing -- that is :)

      I like the discipline, and removal of temptation, that requireing Tk after I've set up my workers brings. The only downside I see is that you have then to use Tk::MainWindow->new(); and Tk::Mainloop() etc. It is even possible to bypass that by an appropriate call to Tk->import (Or is it Tk::import;?), but I never seem to get that right first time.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

      The start of some sanity?

        You seem to be very deeply into perl. Indeed my knowledge of perl is very shallow. First I've tried to develop my app in Visual C++ where I have full and uncompromising control over my Windows system.

        Yet, implementing simple ideas in C++ can get ridiculously complicated. I'm not interested in coding itself but to get my ideas through as simply as possible.

        In perl some 30 characters are enough to generate a window: "use Tk;new MainWindow;MainLoop;" while in C++ you need some 30 _lines_ for the same.

        I'm only interested in your opinion whether PROVIDED that I'm not tempted to use Tk functions in my working thread is it GUARANTEED that my code is safe?