Perl:子线程中变量$^T的值
Perl: the value of variable $^T in child threads
$^T 存储 perl 程序的开始时间,以秒为单位,自纪元以来。
因为我需要知道一个子线程花费了多少秒,所以问题是:
子线程中的 $^T 是否存储自身的开始时间?或者只是从它的母线程中复制值?
运行这个:
#!/usr/bin/env perl
use strict;
use warnings;
sub test_th {
print $^T,"\n";
}
print $^T."\n"
sleep 10;
my $thr = threads -> create ( \&test_th );
$thr -> join;
打印相同的值两次。
正如预期的那样,因为当您线程化时,您实际上继承了所有父变量。
如果您通过分叉尝试此操作:
#!/usr/bin/env perl
use strict;
use warnings;
use Parallel::ForkManager;
print $^T, "\n";
for ( 1 .. 2 ) {
sleep 10;
$mgr->start and next;
print $^T, "\n";
$mgr->finish;
}
$mgr->wait_all_children;
尽管分叉 'start' 晚了 10 秒,但您得到了相同的值。
所以回答你的问题 - 不,$^T
在程序实例化时启动。如果您想测量线程 运行 次之类的东西,则必须找到其他方法。
虽然,鉴于 "elapsed time" 充其量只是一个非常粗略的指标(处理器执行诸如调度之类的事情,因此 'real time' 和 'run time' 并没有特别相关)
但也许在每个线程的开始和结束时调用 time()
可以满足您的需求?或者像 Devel::NYTProf
这样的东西?
快速测试会发现 $^T
是在进程启动时为填充定义的,而不是在线程启动时定义的
但是没有什么能阻止您注意线程何时开始。您甚至可以将时间戳保存在 $^T
中,因为它是一个线程变量!
use feature qw( say );
use threads;
sub thread {
my ($n) = @_;
sleep $n;
}
sub wrapper {
my ($n) = @_;
$^T = time;
thread($n);
say sprintf "Thread %s ran for %s seconds.", threads->tid, time-$^T;
}
async { wrapper(5) };
sleep 2;
async { wrapper(2) };
$_->join for threads->list;
输出:
Thread 2 ran for 2 seconds.
Thread 1 ran for 5 seconds.
请注意,分配给 $^T
会将存储的值强制转换为整数,因此它不适合存储 Time::HiRes::time()
的结果。
$^T 存储 perl 程序的开始时间,以秒为单位,自纪元以来。 因为我需要知道一个子线程花费了多少秒,所以问题是: 子线程中的 $^T 是否存储自身的开始时间?或者只是从它的母线程中复制值?
运行这个:
#!/usr/bin/env perl
use strict;
use warnings;
sub test_th {
print $^T,"\n";
}
print $^T."\n"
sleep 10;
my $thr = threads -> create ( \&test_th );
$thr -> join;
打印相同的值两次。
正如预期的那样,因为当您线程化时,您实际上继承了所有父变量。
如果您通过分叉尝试此操作:
#!/usr/bin/env perl
use strict;
use warnings;
use Parallel::ForkManager;
print $^T, "\n";
for ( 1 .. 2 ) {
sleep 10;
$mgr->start and next;
print $^T, "\n";
$mgr->finish;
}
$mgr->wait_all_children;
尽管分叉 'start' 晚了 10 秒,但您得到了相同的值。
所以回答你的问题 - 不,$^T
在程序实例化时启动。如果您想测量线程 运行 次之类的东西,则必须找到其他方法。
虽然,鉴于 "elapsed time" 充其量只是一个非常粗略的指标(处理器执行诸如调度之类的事情,因此 'real time' 和 'run time' 并没有特别相关)
但也许在每个线程的开始和结束时调用 time()
可以满足您的需求?或者像 Devel::NYTProf
这样的东西?
快速测试会发现 $^T
是在进程启动时为填充定义的,而不是在线程启动时定义的
但是没有什么能阻止您注意线程何时开始。您甚至可以将时间戳保存在 $^T
中,因为它是一个线程变量!
use feature qw( say );
use threads;
sub thread {
my ($n) = @_;
sleep $n;
}
sub wrapper {
my ($n) = @_;
$^T = time;
thread($n);
say sprintf "Thread %s ran for %s seconds.", threads->tid, time-$^T;
}
async { wrapper(5) };
sleep 2;
async { wrapper(2) };
$_->join for threads->list;
输出:
Thread 2 ran for 2 seconds.
Thread 1 ran for 5 seconds.
请注意,分配给 $^T
会将存储的值强制转换为整数,因此它不适合存储 Time::HiRes::time()
的结果。