Reputation: 923
In a CGI webpage, I have a button which when pressed submits a form and a subroutine is called which has:
sub run {
&emailDebug("Started " .localtime);
system("(/tools/script1.pl &) ; (/tools/script2.pl &)");
&emailDebug("Ended " .localtime);
}
They both start at 11:08:05 (hence the fancy command), I take timestamps in the scripts themselves and send them in an email to myself.
The second finished 11:08:22 and the first 11:08:36 but the sent emails from above would show 11:08:06.
Most interestingly, the page is loading for about 30 seconds, as long as the longer of the two scripts run.
I don't mind the page loading but I don't understand why it behaves like this. As the
page is loading, clearly the subroutine run
itself doesn't return, but both emails are sent almost at the same time.
Upvotes: 3
Views: 190
Reputation: 126732
What do you mean by those print statements above? Your code shows no print
calls
Your run
subroutine is returning as soon as the two child processes are started. You could make things clearer by making two calls to system
and removing the parentheses in the command lines. Because of the trailing ampersand both calls to system will return immediately leaving the children to run independently
Something else must be delaying the return of the page after the call to run
, and presumably it is somehow detecting when the work of the child processes is complete
By the way, you should never use an ampersand on a subroutine name when you are making a simple call. It hasn't been necessary since we got Perl 5 eighteen years ago
Upvotes: 1
Reputation: 22421
system
returns as soon as command that you call lets it to. In this particular example it should return immediately, but this may break depending on shell. To be extra sure you might try to just split call in two:
system("/tools/script1.pl &");
system("/tools/script2.pl &");
Also, depending on your web-server configuration, it may notice that you still have STDOUT open in forked childs and it will wait for all them to end before serving response, even if your main script is already ended. Redirect your spawned scripts STDOUT/ERR to /dev/null, close(STDOUT)
and close(STDERR)
in main script or consult your web-server/framework documentation on how to flush response when you're done with output.
Upvotes: 6
Reputation: 97968
You are executing the scripts as background processes so system returns immediately. If you want to wait for completion then remove the &
s and execute them sequentially:
system("(/tools/script1.pl) ; (/tools/script2.pl)");
Upvotes: 2