简体   繁体   中英

How can I make Perl's system() not block?

In my PERL code, i need to do some actions using windows command prompt, example opening notepad ie

system("start notepad");

Now i observed that perl would not move to next statement until previous statement is finished. Is there any way that after sending command to system, perl move to next statement without checking if system task is over.

I made a sample code to explain my issue. I have displayed time after each task here.

use Time::HiRes qw(time);
use POSIX qw(strftime);

####################printing time code starts###########
$t = time;
$date = strftime "%Y%m%d %H:%M:%S", localtime $t;
$date .= sprintf ".%03d", ($t-int($t))*1000; # without rounding
print "Statement 1 executed at $date\n";
#######################printing time code ends###########
####################printing time code starts###########
$t = time;
$date = strftime "%Y%m%d %H:%M:%S", localtime $t;
$date .= sprintf ".%03d", ($t-int($t))*1000; # without rounding
print "Statement 2 executed at $date\n";
#######################printing time code ends#####
system("start notepad");
####################printing time code starts###########
$t = time;
$date = strftime "%Y%m%d %H:%M:%S", localtime $t;
$date .= sprintf ".%03d", ($t-int($t))*1000; # without rounding
print "Statement 3 executed at $date\n";

My output was:

Statement 1 executed at 20150101 19:09:37.614
Statement 2 executed at 20150101 19:09:37.614
Statement 3 executed at 20150101 19:09:37.647

Clearly there is a big difference between statement 2 and statement 3 and i want to avoid it. Please give suggestions.

Note: start notepad is just an example, i may want to copy a 100MB file from 1 folder to another and i dont want perl to wait after sending command to system.

On win32 perl only , you can do:

system( 1, "start notepad" );

to tell system to return right away. This is documented in perlport .

What makes you think that it's waiting for the system call to finish before moving on?

Your test case as written doesn't give a clear indication that would tell us that your assumption is correct. You should adjust the system call so that it does something that is more time consuming, such as doing a dir listing of your complete C drive. That test will show that the "big difference between statement 2 and statement 3" is due to the startup cost of the system function and the Windows start command.

Using ysth's suggested solution will reduce that startup cost.

use strict;
use warnings;
use Time::HiRes qw(time);
use POSIX qw(strftime);

my ($t, $date);

####################printing time code starts###########
$t = time;
$date = strftime "%Y%m%d %H:%M:%S", localtime $t;
$date .= sprintf ".%03d", ($t-int($t))*1000; # without rounding
print "Statement 1 executed at $date\n";
#######################printing time code ends###########
system('');
####################printing time code starts###########
$t = time;
$date = strftime "%Y%m%d %H:%M:%S", localtime $t;
$date .= sprintf ".%03d", ($t-int($t))*1000; # without rounding
print "Statement 2 executed at $date\n";
#######################printing time code ends#####
system("start dir /s C:\\");
####################printing time code starts###########
$t = time;
$date = strftime "%Y%m%d %H:%M:%S", localtime $t;
$date .= sprintf ".%03d", ($t-int($t))*1000; # without rounding
print "Statement 3 executed at $date\n";

Statement 1 executed at 20150101 07:23:04.745
Statement 2 executed at 20150101 07:23:04.757
Statement 3 executed at 20150101 07:23:04.767

After adding the additional parameter to the system call, here are the new times.

Statement 1 executed at 20150101 07:27:56.333
Statement 2 executed at 20150101 07:27:56.355
Statement 3 executed at 20150101 07:27:56.356

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM