为什么我的 ActivePerl 程序报告“抱歉。”线程用完了?

发布于 2024-08-25 05:56:49 字数 1499 浏览 8 评论 0原文

Tom Christiansen 的示例代码(类似于 perlthrtut) 是一个递归、线程实现,用于查找和打印 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),然后以“抱歉”终止。线程不足'警告。

在试图弄清楚为什么我可以创建的线程数量受到限制时,我将 usethreads; 行替换为 usethreads (stack_size => 1); 。最终的代码可以愉快地处理 2000 多个线程。

谁能解释这种行为?

Tom Christiansen's example code (à la perlthrtut) is a recursive, threaded implementation of finding and printing all prime numbers between 3 and 1000.

Below is a mildly adapted version of the script

#!/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);

When run on my machine (under ActiveState & Win32), the code was capable of spawning only 118 threads (last prime number found: 653) before terminating with a 'Sorry. Ran out of threads' warning.

In trying to figure out why I was limited to the number of threads I could create, I replaced the use threads; line with use threads (stack_size => 1);. The resultant code happily dealt with churning out 2000+ threads.

Can anyone explain this behavior?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

睡美人的小仙女 2024-09-01 05:56:49

来自 线程文档

不同平台的默认每线程堆栈大小差异很大,并且几乎总是远远超过大多数应用程序所需的大小。在 Win32 上,Perl 的 makefile 显式地将默认堆栈设置为 16 MB;在大多数其他平台上,使用系统默认值,该值可能又比需要的大得多。

通过调整堆栈大小以更准确地反映应用程序的需求,您可以显着减少应用程序的内存使用量,并增加同时运行的线程数。

请注意,在 Windows 上,地址空间分配粒度为 64 KB,因此,将堆栈设置为小于 Win32 Perl 上的堆栈不会节省更多内存。

From the threads documentation:

The default per-thread stack size for different platforms varies significantly, and is almost always far more than is needed for most applications. On Win32, Perl's makefile explicitly sets the default stack to 16 MB; on most other platforms, the system default is used, which again may be much larger than is needed.

By tuning the stack size to more accurately reflect your application's needs, you may significantly reduce your application's memory usage, and increase the number of simultaneously running threads.

Note that on Windows, address space allocation granularity is 64 KB, therefore, setting the stack smaller than that on Win32 Perl will not save any more memory.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文