in reply to threads on Windows
Ignoring for a moment all the other "advise" in this thread, I have a question.
Given that, as your comments suggests, using enqueue() directly:
#$Q_found->enqueue( $cmd ) ; # using this in place of async works
Rather than starting a whole new thread for the sole purpose of doing something that takes approximately 1/1000 of the time it takes to start that thread, the program runs perfectly:
c:\test>junk9 Create terminal watcher... Awaiting commands... fred fred bill bill john john quit Resolving open threads
Why are you starting that thread?
But then, why are you queuing to a second queue from your main loop, when the only thing you do with what you queue, is to dequeue it later from that same main loop?
Which also means that you have to use dequeue_nb() rather than dequeue(), which in turn forces you to use sleep to stop it from running away with the cpu. Using non-blocking dequeue makes a complete nonsense of a message passing architecture.
Even your OP code works--as you've designed it, though possibly not as you expect--on Win32. The ONLY change I've made is to prefix the output with '>' to differentiate it from the input:
#!/usr/bin/perl use strict; use warnings; use threads; use Thread::Queue; # Create terminal watcher print "Create terminal watcher...\n"; my $Q_stdin = Thread::Queue->new; async { $Q_stdin->enqueue( $_ ) while defined( $_ = <STDIN> ); }->detach; my $Q_found = Thread::Queue->new; my $cmd; print "Awaiting commands...\n"; MAIN_LOOP: while (not defined $cmd or $cmd !~ /^q/i) { sleep(1); # Reduce load # Process commands $cmd = $Q_stdin->dequeue_nb; if (defined $cmd) { chomp $cmd; if ($cmd =~ /^q/i) { print "Resolving open threads\n"; } else { async { $Q_found->enqueue( $cmd ) ; }->detach; #$Q_found->enqueue( $cmd ) ; # using this in place of asyn +c works } } # Print announcements while (defined(my $output = $Q_found->dequeue_nb)) { print ">$output\n"; } } __END__ c:\test>junk9 Create terminal watcher... Awaiting commands... fred bill john >fred mary >bill quit >john Resolving open threads >mary
Why do you not get the first output until after the third input? Because that's exactly the way you've designed it to work.
Why does it work differently on Win32 to *nix? Because they are different systems. Specifically, the OS serialises read and write accesses to console devices.
Can I prove this is the case? Yes. If you supply the input via a pipe, rather than from the keyboard, then you'll see the bahaviour you are (wrongly) expecting:
c:\test>perl -wle" printf qq[%08d\n], $_ for 1 .. 10; print 'quit' " | + perl junk9.pl Create terminal watcher... Awaiting commands... >00000001 >00000002 >00000003 >00000004 >00000005 >00000006 >00000007 >00000008 >00000009 Resolving open threads >00000010
If you would describe what you are actually trying to do, I can probably suggest a simpler and more consistant architecture.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: threads on Windows
by kennethk (Abbot) on Feb 12, 2009 at 17:19 UTC | |
by BrowserUk (Patriarch) on Feb 13, 2009 at 04:09 UTC | |
by kennethk (Abbot) on Feb 13, 2009 at 17:48 UTC | |
by BrowserUk (Patriarch) on Feb 13, 2009 at 20:37 UTC | |
by kennethk (Abbot) on Feb 17, 2009 at 22:45 UTC | |
|