Tom Christiansen's example code(àlaperlthrtut)是一个递归的线程实现,用于查找和打印3到1000之间的所有素数。
以下是脚本的适度修改版本
#!/usr/bin/perl
# adapted from prime-pthread, courtesy of Tom Christiansen
use strict;
use warnings;
use threads;
use Thread::Queue;
sub check_prime {
my ($upstream,$cur_prime) = @_;
my $child;
my $downstream = Thread::Queue->new;
while (my $num = $upstream->dequeue) {
next unless ($num % $cur_prime);
if ($child) {
$downstream->enqueue($num);
} else {
$child = threads->create(\&check_prime, $downstream, $num);
if ($child) {
print "This is thread ",$child->tid,". Found prime: $num\n";
} else {
warn "Sorry. Ran out of threads.\n";
last;
}
}
}
if ($child) {
$downstream->enqueue(undef);
$child->join;
}
}
my $stream = Thread::Queue->new(3..shift,undef);
check_prime($stream,2);
在我的机器上运行时(在ActiveState& Win32下),代码只能生成118个线程(找到的最后一个素数:653),然后以“Sorry. Ran out of threads
”警告终止。
在试图弄清楚为什么我被限制为我可以创建的线程数时,我将use threads;
行替换为use threads (stack_size => 1);
。由此产生的代码很好地处理了生成2000多个线程。
任何人都可以解释这种行为吗?
答案 0 :(得分:3)
不同平台的默认每线程堆栈大小差异很大,几乎总是远远超过大多数应用程序所需的大小。在Win32上,Perl的makefile显式地将默认堆栈设置为16 MB;在大多数其他平台上,使用系统默认值,这可能比需要的大得多。
通过调整堆栈大小以更准确地反映应用程序的需求,可以显着减少应用程序的内存使用量,并增加同时运行的线程数。
请注意,在Windows上,地址空间分配粒度为64 KB,因此,将堆栈设置为小于Win32 Perl上的堆栈将不会节省更多内存。