I scattered print statements around to see if that told me any more about what is happening here -- as below. I tried this on Windows XP, Activestate 5.10.0 (1004).
What I saw was roughly what you described, the main thread seemed to hang trying to create the new thread (ie on the async in the MAIN_LOOP) -- but only until the input thread got something from STDIN.
I tried adding a sleep(2) after enqueuing the input (where shown in the code below). Now things worked more as expected -- the main thread no longer hangs.
Under Windows, what appears to be going on is: the main thread is hanging trying to create a new thread, while the input thread is waiting on STDIN.
Now... we know that when a new thread is created the entire state of the creator thread is duplicated. That includes filehandles. My guess (and this is only a guess) is that the duplication of STDIN is blocked while another thread is waiting on it (or otherwise "owns it").
If the main thread closes STDIN after creating the input thread, then all is well.
Trying to share an input across a number of threads is obviously tricky. I can see the logic of having an exclusive lock on a file handle -- who knows, it may even support multiple threads reading a line at a time from a shared filehandle. I don't know how *n*x deals with this.
So, I guess the lesson here is that tidiness is next to working code. When you no longer have a legitimate interest in a file handle, close the sucker.
use strict; use warnings; use threads; use Thread::Queue; $|++ ; # Create terminal watcher print "Create terminal watcher...\n"; my $Q_stdin = Thread::Queue->new; async { while (defined( $_ = <STDIN> )) { chomp ; print "\n+IN : '$_' " ; $Q_stdin->enqueue( $_ ) ; # print "|" ; sleep(2) ; ### Optional sleep() after inpu +t <<<< print "*" ; } ; }->detach; # close STDIN ; ### no longer our business + <<<< my $Q_found = Thread::Queue->new; my $cmd; print "Awaiting commands...\n"; MAIN_LOOP: while (not defined $cmd or $cmd !~ /^q/i) { print "_" ; sleep(1); # Reduce load print "." ; # Process commands $cmd = $Q_stdin->dequeue_nb; if (defined $cmd) { print "\n-IN : '$cmd' " ; if ($cmd =~ /^q/i) { print "\nResolving open threads\n"; } else { async { print "\n+OUT: '$cmd' " ; $Q_found->enqueue( $cmd ) ; }->detach; } } # Print announcements while (defined(my $output = $Q_found->dequeue_nb)) { print "\n-OUT: '$output' "; } }
In reply to Re: threads on Windows
by gone2015
in thread threads on Windows
by kennethk
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |