in reply to Re: threads on Windows
in thread threads on Windows

Confirmed that adding sleep to my text input thread resolves the issue. I don't get any significant behavioral change w/ closing STDIN, so I conclude that the issue is that <> blocks (waiting on input) while the main thread is blocked at async (waiting for a free control), resulting in a race condition whenever the IO thread receives a line. The *NIX box has an unfair advantage here since it's running off a quad core, thus it has enough control to allow three threads at once. Since my ultimate plan was replacing the STDIN reading thread with a GUI thread, I'll have to see how it behaves with regard to control issues (I'm seeing run-time thread safety determination in my future...).

Thanks so much for your help.

Replies are listed 'Best First'.
Re^3: threads on Windows
by gone2015 (Deacon) on Feb 12, 2009 at 17:21 UTC

    Hmmm... that's odd. I found that the close STDIN did the job perfectly. I note you are using ActiveState perl v5.8.8 on a dual core machine -- while I have 5.10.0, single core... but have no way of knowing whether either accounts for the difference.

    Just in case: it's not necessary to have the sleep in the input thread and the close together... the close on its own does the trick (here).

    I wondered whether it made a difference if the input thread was blocked on the <STDIN> at the time the main thread did the close STDIN in the main thread to block or fail... which would be more likely on a dual core machine. However, I tried a threads->yield() before the close, and that didn't make any difference. (The input loop was definitely waiting for <STDIN> but the close completed successfully.)I suppose this could be different on 5.8.8 ?

    If you wanted to play with semaphores you could do:

    # Create terminal watcher print "Create terminal watcher...\n"; my $Q_stdin = Thread::Queue->new ; my $S_stdin = Thread::Semaphore->new(0) ; print "fileno(STDIN) = ", fileno(STDIN), "\n" ; async { $S_stdin->down() ; print "Reading STDIN, fileno=", fileno(STDIN), "\n" ; while (defined( $_ = <STDIN> )) { chomp ; print "\n+IN : '$_' " ; $Q_stdin->enqueue( $_ ) ; print "*" ; } ; }->detach; close STDIN ; ### no longer our business + <<<< print "STDIN is: ", defined(fileno(STDIN)) ? 'open' : 'closed', "\n" ; $S_stdin->up() ;
    which guarantees that the main thread has closed STDIN before the input thread touches it.

      Your new code inserted in does the trick, which makes me totally buy your explanation. Thanks a bunch.