我怎样才能使 Perl 的 system() 不阻塞?
How can I make Perl's system() not block?
在我的 PERL 代码中,我需要使用 windows 命令提示符执行一些操作,例如打开记事本即
system("start notepad");
现在我观察到 perl 在上一个语句完成之前不会移动到下一个语句。有什么方法可以在向系统发送命令后,perl 移动到下一条语句而不检查系统任务是否结束。
我做了一个示例代码来解释我的问题。我在这里显示了每个任务完成后的时间。
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";
我的输出是:
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
显然,陈述 2 和陈述 3 之间存在很大差异,我想避免它。请给点建议。
注意:启动记事本只是一个例子,我可能想将一个 100MB 的文件从一个文件夹复制到另一个文件夹,我不希望 perl 在向系统发送命令后等待。
仅在 win32 perl 上,您可以:
system( 1, "start notepad" );
立即告诉系统return。这记录在 perlport.
中
是什么让您认为它在等待系统调用完成后再继续?
您编写的测试用例没有给出明确的指示来告诉我们您的假设是正确的。你应该调整系统调用,让它做一些更耗时的事情,比如做一个完整的 C 驱动器的目录列表。该测试将显示 "big difference between statement 2 and statement 3" 是由于系统功能和 Windows start 命令的启动成本。
使用 ysth 建议的解决方案将降低启动成本。
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";
语句 1 执行于 20150101 07:23:04.745
语句 2 在 20150101 07:23:04.757
执行
语句 3 在 20150101 07:23:04.767
执行
将附加参数添加到系统调用后,这是新的时间。
语句 1 执行于 20150101 07:27:56.333
20150101执行语句207:27:56.355
语句 3 在 20150101 07:27:56.356
执行
在我的 PERL 代码中,我需要使用 windows 命令提示符执行一些操作,例如打开记事本即
system("start notepad");
现在我观察到 perl 在上一个语句完成之前不会移动到下一个语句。有什么方法可以在向系统发送命令后,perl 移动到下一条语句而不检查系统任务是否结束。
我做了一个示例代码来解释我的问题。我在这里显示了每个任务完成后的时间。
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";
我的输出是:
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
显然,陈述 2 和陈述 3 之间存在很大差异,我想避免它。请给点建议。
注意:启动记事本只是一个例子,我可能想将一个 100MB 的文件从一个文件夹复制到另一个文件夹,我不希望 perl 在向系统发送命令后等待。
仅在 win32 perl 上,您可以:
system( 1, "start notepad" );
立即告诉系统return。这记录在 perlport.
中是什么让您认为它在等待系统调用完成后再继续?
您编写的测试用例没有给出明确的指示来告诉我们您的假设是正确的。你应该调整系统调用,让它做一些更耗时的事情,比如做一个完整的 C 驱动器的目录列表。该测试将显示 "big difference between statement 2 and statement 3" 是由于系统功能和 Windows start 命令的启动成本。
使用 ysth 建议的解决方案将降低启动成本。
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";
语句 1 执行于 20150101 07:23:04.745
语句 2 在 20150101 07:23:04.757
执行
语句 3 在 20150101 07:23:04.767
将附加参数添加到系统调用后,这是新的时间。
语句 1 执行于 20150101 07:27:56.333
20150101执行语句207:27:56.355
语句 3 在 20150101 07:27:56.356