Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Running a perl script as a system command in another thread hangs while main thread reading from STDIN

by rmahin (Scribe)
on Sep 30, 2014 at 00:14 UTC ( #1102396=perlquestion: print w/replies, xml ) Need Help??
rmahin has asked for the wisdom of the Perl Monks concerning the following question:

Hi perlmonks, have run into a weird issue. In this program, the main thread is reading from STDIN, and other threads are issuing system commands in the background. The weird part is that it only seems to cause a problem when the system command is a perl command. Have tested this on Windows 7 and Windows 2012 R2.UPDATE 2: This affects all Windows 8, and Windows 2012 platforms that I have used.

This is not the original code I found, but a simplified script that I hope adequately demonstrates the issue. If the script is run with input, it simply executes echo hello world, if it is given input it will run perl -e "print \"hello world\""

My hunch would be that reading from STDIN is preventing perl from performing the fork, which would make sense if it had this problem with all system commands but it seems to be limited to perl, or something else that I am not seeing. My first thought was to close STDIN in the thread, but this didn't seem to make any difference. Hopefully one you has some idea of whats going on here :/

#! perl use strict; use warnings; use threads; use threads::shared; my $startTime = time(); $|++; my $semSTDOUT :shared; sub tprint{ lock $semSTDOUT; print STDERR (time() - $startTime) . "s : Thread " . threads->tid +() . " - " . join(" ", @_) . "\n"; } my $command; if (@ARGV) { print "### Running a perl script ###\n"; $command = 'perl -e "print \"hello world\""'; }else{ print "### Running a regular command ###\n"; $command = 'echo hello world'; } #all of these threads will be created while main thread is not reading + from stdin tprint("> Creating threads"); my @threads; #threads that will execute command after main thread is reading from s +tdin again push @threads, threads->create('threadWait') for 1..3; sleep 1; tprint("All Threads created"); tprint("> Waiting for input now. All threads should finish now without + pressing enter"); <STDIN>; tprint("> Input received, all done"); $_->join() for @threads; tprint("All Threads joined"); exit 0; sub threadWait{ #close STDIN; #seemed to have no effect... tprint("Created"); sleep 3;#just give main thread a little extra time to read stdin tprint("Starting '$command'"); my $output = `$command`; chomp $output; tprint("Finished the command: $output"); }

This yields the following output

C:\>test.pl ### Running a regular command ### 0s : Thread 0 - > Creating threads 1s : Thread 1 - Created 1s : Thread 2 - Created 1s : Thread 3 - Created 2s : Thread 0 - All Threads created 2s : Thread 0 - > Waiting for input now. All threads should finish now + without pressing enter 4s : Thread 1 - Starting 'echo hello world' 4s : Thread 2 - Starting 'echo hello world' 4s : Thread 3 - Starting 'echo hello world' 4s : Thread 1 - Finished the command: hello world 4s : Thread 2 - Finished the command: hello world 4s : Thread 3 - Finished the command: hello world <-- pressed enter here 7s : Thread 0 - > Input received, all done 7s : Thread 0 - All Threads joined C:\>test.pl 1 ### Running a perl script ### 0s : Thread 0 - > Creating threads 0s : Thread 1 - Created 0s : Thread 2 - Created 0s : Thread 3 - Created 1s : Thread 0 - All Threads created 1s : Thread 0 - > Waiting for input now. All threads should finish now + without pressing enter 3s : Thread 1 - Starting 'perl -e "print \"hello world\""' 3s : Thread 3 - Starting 'perl -e "print \"hello world\""' 3s : Thread 2 - Starting 'perl -e "print \"hello world\""' <-- pressed enter here 8s : Thread 0 - > Input received, all done 8s : Thread 1 - Finished the command: hello world 8s : Thread 3 - Finished the command: hello world 8s : Thread 2 - Finished the command: hello world 8s : Thread 0 - All Threads joined

Thanks for taking a look!

UPDATE: Including perl -v output. This is the same for both 2012 systems that are affected by this issue. Other operating systems seem to be unaffected.

C:\>perl -v This is perl 5, version 18, subversion 2 (v5.18.2) built for MSWin32-x +64-multi-thread (with 1 registered patch, see perl -V for more detail) Copyright 1987-2013, Larry Wall Binary build 1801 [297964] provided by ActiveState http://www.ActiveSt +ate.com Built Feb 24 2014 11:06:47 Perl may be copied only under the terms of either the Artistic License + or the GNU General Public License, which may be found in the Perl 5 source ki +t. Complete documentation for Perl, including FAQ lists, should be found +on this system using "man perl" or "perldoc perl". If you have access to + the Internet, point your browser at http://www.perl.org/, the Perl Home Pa +ge.

UPDATE 3 - Workaround: On a whim, I decided to try piping nul to the perl process. Surprisingly, it seems to work..

C:\>test.pl 1 ### Running a perl script ### 0s : Thread 0 - > Creating threads 0s : Thread 1 - Created 0s : Thread 2 - Created 0s : Thread 3 - Created 1s : Thread 0 - All Threads created 1s : Thread 0 - > Waiting for input now. All system commands should fi +nish without pressing enter 3s : Thread 1 - Starting 'perl -e "print \"hello world\"" < nul' 3s : Thread 3 - Starting 'perl -e "print \"hello world\"" < nul' 3s : Thread 2 - Starting 'perl -e "print \"hello world\"" < nul' 3s : Thread 3 - Finished the command: hello world 3s : Thread 1 - Finished the command: hello world 3s : Thread 2 - Finished the command: hello world 7s : Thread 0 - > Input received, all done 7s : Thread 0 - All Threads joined
  • Comment on Running a perl script as a system command in another thread hangs while main thread reading from STDIN
  • Select or Download Code

Replies are listed 'Best First'.
Re: Running a perl script as a system command in another thread hangs while main thread reading from STDIN
by BrowserUk (Pope) on Sep 30, 2014 at 00:31 UTC

    I see no difference between the two runs of the program;

    and nor would I expect to.

    The threads won't terminate until they are joined; and they won't be joined until the code moves past <STDIN>; to the join loop.


    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.

      Thanks for your response. Well, shoot. I tested this again on my Windows 7 machine, actually running from command line (before was running from the built in shell of Komodo Edit) and I do see that it works as expected. I apologize for the incorrect assessment. Tested against a Windows 2008 R2 machine, and saw the correct behavior as well. Windows 2012 R2 however, is still behaving abnormally. I tested on another Windows 2012 (not R2) and found the same problem. I'm glad this is the case, considering the 2012 machine is where we first noticed the problem, and this means we do not all of a sudden have a widespread problem in our code. However, it does not help me solve the problem. Which there is...somewhere.

      The trouble is not with the threads terminating (agreed, the message I printed was misleading), but with the system command being run. Perl processes start up, but they do not terminate. Given that I'm executing a single print statement I would expect these processes to disappear rather quickly and not linger until I hit enter in the test script. Have any ideas or advice on how to debug this issue further?

      C:\>perl -v This is perl 5, version 18, subversion 2 (v5.18.2) built for MSWin32-x +64-multi-thread (with 1 registered patch, see perl -V for more detail) Copyright 1987-2013, Larry Wall Binary build 1801 [297964] provided by ActiveState http://www.ActiveSt +ate.com Built Feb 24 2014 11:06:47 Perl may be copied only under the terms of either the Artistic License + or the GNU General Public License, which may be found in the Perl 5 source ki +t. Complete documentation for Perl, including FAQ lists, should be found +on this system using "man perl" or "perldoc perl". If you have access to + the Internet, point your browser at http://www.perl.org/, the Perl Home Pa +ge. C:\>perl test.pl 1 ### Running a perl script ### 0s : Thread 0 - > Creating threads 0s : Thread 1 - Created 0s : Thread 2 - Created 0s : Thread 3 - Created 1s : Thread 0 - All Threads created 1s : Thread 0 - > Waiting for input now. All system commands should fi +nish without pressing enter 3s : Thread 2 - Starting 'perl -e "print \"hello world\""' 3s : Thread 3 - Starting 'perl -e "print \"hello world\""' 3s : Thread 1 - Starting 'perl -e "print \"hello world\""' 68s : Thread 0 - > Input received, all done 68s : Thread 1 - Finished the command: hello world 68s : Thread 2 - Finished the command: hello world 68s : Thread 3 - Finished the command: hello world 68s : Thread 0 - All Threads joined

        Could you try adding the -l option to your perl one line and try it on the errant system(s).


        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.
Re: Running a perl script as a system command in another thread hangs while main thread reading from STDIN
by Anonymous Monk on Mar 16, 2015 at 03:50 UTC
    Thank you for this post. I came across this issue while calling perl scripts from Informatica Powercenter 9.6 on windows 2012 R2. We were on Windows 2003 and Informatica and these perl script always ran fine in that environment. But, when I added "< nul" while calling the perl script, the issue got resolved. Thanks once again.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1102396]
Approved by biohisham
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (5)
As of 2018-05-23 19:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Notices?