I am in Windows running a Perl script that calls an executable:
$command = "$path_to_exe -i $dir -o $results";
my $pid = fork();
if ( !$pid ) {
system($command);
#do stuff
} else {
#do stuff
}
print "Exiting..."
exit;
Instead of exiting after, perl.exe just idles. A pop-up then tells me that the "Perl command line interpreter has stopped working."
I don't know very much about process management in Windows, and I have read previously on this forum that it's not good practice to use fork()
and exec()
, but the code works well besides the interpreter not closing part. I've tried everything from trying to implement the program in Unix (which gives the same error) to using Win32::Process
commands -- but nothing works. I hoped there might be a simpler solution that would allow me to preserve what I've already written.
If anyone could explain what exactly is happening in Windows when this code is run, that would be a help too!
The Perl Compiler. Threads. The perl executable, normally installed in /usr/bin or /usr/local/bin on your machine, is also called the perl interpreter . Every Perl program must be passed through the Perl interpreter in order to execute. The first line in many Perl programs is something like: #!/usr/bin/perl.
The normal way to run a Perl program is by making it directly executable, or else by passing the name of the source file as an argument on the command line. (An interactive Perl environment is also possible--see perldebug for details on how to do that.)
The default, out of the box, Perl interpreter is found in $NH_HOME/web/aview/perl/bin/perl. To run a Perl script in Windows, the following procedure should be used: Open a DOS command prompt via Start->Run->cmd. cd to the directory where the script has been saved.
I can see 2 independent problems.
system()
creates a child process, thus if you call a system()
from a forked child, you will have 3 processes. But you kill only the second (the forked child), and the child of the child (the $command) not. Try to use some function like exec()
, on unix it starts the child process on the place (and on the pid) of the actual process. If you have luck, Perl on Windows does the same.
in the parent thread you kill $$
, which is the current process. Probably you wanted to kill $pid
(which is the pid of the child process on the parent thread).
I used the following (it times out the program and, most importantly, doesn't break the Perl interpreter!):
use Win32::Job;
my $job = Win32::Job->new;
# Run $command for $max_time
$job->spawn($Config{"path/cmd.exe"}, $command);
$job->run($max_time);
exit;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With