2010-03-14 16 views
2

Tom Christiansen's example code (à la perlthrtut) est une implémentation récursive, filetée de la recherche et l'impression de tous les nombres premiers entre 3 et 1000.Pourquoi mon programme ActivePerl signale-t-il 'Désolé. Ran hors de threads?

est inférieure à une version légèrement adaptée du 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); 

Lorsqu'il est exécuté sur mon machine (sous ActiveState & Win32), le code était capable de générer seulement 118 threads (dernier nombre premier trouvé: 653) avant de se terminer avec un avertissement 'Sorry. Ran out of threads'. En essayant de comprendre pourquoi je me limitais au nombre de threads que je pouvais créer, j'ai remplacé la ligne use threads; par use threads (stack_size => 1);. Le code résultant a heureusement traité avec plus de 2000 threads.

Quelqu'un peut-il expliquer ce comportement?

Répondre

3

De l'threads documentation:

La taille de la pile par défaut par thread pour différentes plates-formes varie considérablement, et est presque toujours beaucoup plus que ce qui est nécessaire pour la plupart des applications. Sur Win32, le makefile de Perl définit explicitement la pile par défaut à 16 Mo; Sur la plupart des autres plates-formes, le système par défaut est utilisé, ce qui peut être beaucoup plus grand que nécessaire.
En ajustant la taille de la pile pour mieux refléter les besoins de votre application, vous pouvez réduire considérablement l'utilisation de la mémoire de votre application et augmenter le nombre de threads en cours d'exécution simultanément. Notez que sous Windows, la granularité d'allocation d'espace d'adressage est de 64 Ko. Par conséquent, si la taille de la pile est inférieure à celle de Win32 Perl, la mémoire ne sera plus sauvegardée.

+0

Ceci est intéressant. En utilisant '$ child-> get_stack_size;' j'obtiens '8096'. Je suppose que c'est en octets, non? – Zaid

+0

La documentation de Windows (http://msdn.microsoft.com/en-us/library/ms686774%28VS.85%29.aspx) mentionne également 64 kByte comme une taille typique, pour trouver la taille réelle que vous devez appeler le GetSystemInfo. C'est quelque chose qui pourrait même dépendre de l'architecture CPU. – weismat

+0

Ce lien (http://www.perlmonks.org/?node_id=31432) peut vous aider à obtenir les données de perl. – weismat