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

Is there any alternative way to work around this problem? Methods using 'alarm' in any shape or form as a timeout watcher also don't work on Windows.

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

Currently I do the engine stuff in a separate multi threaded non-Tk perl program, which copies the output of the engine to an ordinary file which the main app can read. This way however I have to run two different programs.

Replies are listed 'Best First'.
Re^3: bidirectional pipe freezing
by Corion (Patriarch) on Dec 21, 2011 at 14:02 UTC

    There is IPC::Run, but my approach to this has always been to do a (blocking) read from the pipe in a separate thread and stuff the lines into a Thread::Queue, from where the front end code (or whatever else) reads.

Re^3: bidirectional pipe freezing
by BrowserUk (Patriarch) on Dec 21, 2011 at 15:03 UTC
    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?

      @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?