in reply to bidirectional pipe freezing

Yes, select doesn't work on win32 for pipes, only for sockets, see [Win32] IO::Select's can_read method, win32 and select

Replies are listed 'Best First'.
Re^2: bidirectional pipe freezing
by chessgui (Scribe) on Dec 21, 2011 at 13:52 UTC
    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.

      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.

      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"); } ######################################################