Почему моя программа ActivePerl сообщает «Извините. Закончились темы? - PullRequest
2 голосов
/ 14 марта 2010

Пример кода Тома Кристиансена (à la 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), а затем завершаться с предупреждением 'Sorry. Ran out of threads'.

Пытаясь выяснить, почему я был ограничен числом потоков, которые я мог создать, я заменил строку use threads; на use threads (stack_size => 1);. Результирующий код успешно справился с созданием более 2000 потоков.

Может кто-нибудь объяснить это поведение?

1 Ответ

3 голосов
/ 14 марта 2010

Из документации :

Размер стека по умолчанию для разных потоков значительно различается и почти всегда намного больше, чем требуется для большинства приложений. В Win32 make-файл Perl явно устанавливает стек по умолчанию 16 МБ; на большинстве других платформ используется системное значение по умолчанию, которое может быть намного больше, чем необходимо.
Настроив размер стека для более точного отражения потребностей вашего приложения, вы можете значительно сократить использование памяти вашим приложением и увеличить количество одновременно работающих потоков.
Обратите внимание, что в Windows степень детализации распределения адресного пространства составляет 64 КБ, поэтому установка стека меньшего размера, чем в Win32 Perl, больше не экономит память.

...