title: perl threads self detach
body: <p>I'm pretty new to perl (and programming too) and were toying around with threads for the last couple of weeks and so far I understood that using them to perform some similar parallel tasks is descouraged - memory consumption is uncontrollable if your number of threads depends on some input values, and simply limiting that number and doing some interim joins seems pretty much silly.
  So I've tried to trick threads to return me some values through queues followed by detaching those threads (and without actually joining them) - here's an example with parallel ping:</p>
  
  <pre><code>#!/usr/bin/perl
  #
  
  use strict;
  use warnings;
  use threads;
  use NetAddr::IP;
  use Net::Ping;
  use Thread::Queue;
  use Thread::Semaphore;
  ########## get my IPs from CIDR-notation #############
  my @ips;
  for my $cidr (@ARGV) {
      my $n = NetAddr::IP-&gt;new($cidr);
      foreach ( @{ $n-&gt;hostenumref } ) {
          push @ips, ( split( '/', $_ ) )[0];
      }
  }
  
  my $ping      = Net::Ping-&gt;new("icmp");
  my $pq        = Thread::Queue-&gt;new( @ips, undef );    # ping-worker-queue
  my $rq        = Thread::Queue-&gt;new();                 # response queue
  my $semaphore = Thread::Semaphore-&gt;new(100);          # I hoped this may be usefull to limit # of concurrent threads
  
  while ( my $phost = $pq-&gt;dequeue() ) {
      $semaphore-&gt;down();
      threads-&gt;create( { 'stack_size' =&gt; 32 * 4096 }, \&amp;ping_th, $phost );
  }
  
  sub ping_th {
      $rq-&gt;enqueue( $_[0] ) if $ping-&gt;ping( $_[0], 1 );
      $semaphore-&gt;up();
      threads-&gt;detach();
  }
  
  $rq-&gt;enqueue(undef);
  
  while ( my $alive_ip = $rq-&gt;dequeue() ) {
      print $alive_ip, "\n";
  }
  </code></pre>
  
  <p>I couldn't find a fully comprehensive description of how threads->detach() should work from within a threaded subroutine and thought that this might work... and it does - if I do something in the main program (thread) that stretches it's lifetime (sleep does well), so all the detached threads finish up and enqueue their part to my $rq, otherwise it will run some threads collect their results to the queue and exit with warnings like:</p>
  
  <pre><code>Perl exited with active threads:
      5 running and unjoined
      0 finished and unjoined
      0 running and detached
  </code></pre>
  
  <p>Making the main program "sleep" for a while, once again, seems silly - is there no way to make threads do their stuff and detach ONLY after the actual threads->detach() call?
  So far my guess is that threads->detach() inside a sub applies as soon as the thread is created and so this is not the way.
  I tried this out with CentOSs good old v5.10.1. Should this change with modern v5.16 or v5.18 (usethreads-compiled)?</p>