title: Parallel execution of command using Parallel::ForkManager
body: <p>I want to know whether my understanding is right or not for the below script/logic.</p>
  <p>I have list of nodes and I need to run a certain command on each of the node by utilizing number of servers which I have by doing SSH to the servers, means the process should happen parallelly.</p>
  <p>I have <code>node_list.txt</code> file which contains list of nodes:</p>
  <pre><code>node1
  node2
  .
  .
  node49
  node50
  
  </code></pre>
  <p>I have defined number of servers in an array <code>@hosts</code> where I should do SSH and execute the command to each node by splitting the <code>node_file.txt</code> into equal number of parts(called <code>$node_list_X.txt</code>) in an available servers.</p>
  <p>Once I have these files (<code>node_list_1.txt</code>,<code>node_list_2.txt</code>,<code>node_list_3.txt</code>,<code>node_list_4.txt</code>) I will be logging into each the server which is already been defined and executing certain commands on each hosts by passing <code>node_list_X.txt</code> file parallelly.</p>
  <p>To execute this parallelly I am using <code>Parallel::ForkManager</code> Perl module.</p>
  <p>So that, lets say in each host -</p>
  <pre><code>192.168.0.1 -&gt; node_list_1.txt (13 nodes)
  192.168.0.2 -&gt; node_list_2.txt (13 nodes)
  192.168.0.3 -&gt; node_list_3.txt (12 nodes)
  192.168.0.4 -&gt; node_list_4.txt (12 nodes)
  </code></pre>
  <p>will run parallelly.</p>
  <p>Script is below:</p>
  <pre><code>...
  my @hosts = (&quot;192.168.0.1&quot;, &quot;192.168.0.2&quot;, &quot;192.168.0.3&quot;,&quot;192.168.0.4&quot;);
  
  open(my $node_fh, '&lt;', $node_file)
          or die &quot;can't open $node_file: $!&quot;;
  
  my @lines =  &lt;$node_fh&gt;;
  
  my %Files;
  
  my $num_buckets = scalar @hosts;
  
  my $per_bucket = int( @lines / $num_buckets );
  my $num_extras =      @lines % $num_buckets;
  my $path = &quot;/home/user/vinod/test/&quot;;
  
  for my $bucket_num (0..$num_buckets-1) {
     my $num_lines = $per_bucket;
     if ($num_extras) {
        ++$num_lines;
        --$num_extras;
     }
  
     last if($num_lines == 0);
     my $qfn = $path.&quot;node_list_${bucket_num}.txt&quot;;
     open(my $fh, '&gt;', $qfn)
        or die(&quot;Can't create \&quot;$qfn\&quot;: $!\n&quot;);
  
     $fh-&gt;print(splice(@lines, 0, $num_lines));
     $Files{$bucket_num} = $qfn;
  }
  print Dumper(\%Files);
  
  my $command = #&quot;defining my command here&quot;;
  
  my $pm = Parallel::ForkManager-&gt;new(5);
  my $ssh;
  
  DATA_LOOP:
  foreach my $n (0..$num_buckets-1) {
      if( exists $Files{$n} ) {
          my $pid = $pm-&gt;start and next DATA_LOOP;
  
          $command_to_execute = $command.&quot; &quot;.$Files{$n};
          $ssh = SSH_Connection( $hosts[$n-1], &quot;user&quot;, &quot;password&quot; );
          $result = $ssh-&gt;capture($command_to_execute);
        
          $pm-&gt;finish;       
      }
  }
  $pm-&gt;wait_all_children;
  undef $ssh;
  
  #SSH Connect
  sub SSH_Connection {
      my ( $host, $user, $passwd ) = @_;
      my $ssh = Net::OpenSSH-&gt;new($host,
                                  user =&gt; $user,
                                  password =&gt; $passwd,
                                  master_opts =&gt; [-o =&gt; &quot;StrictHostKeyChecking=no&quot;]
      );
      $ssh-&gt;error and die &quot;Couldn't establish SSH connection: &quot;. $ssh-&gt;error;
      return $ssh;
  }
  </code></pre>
  <p>Here everything works fine.</p>
  <p>When I am defining <code>$pm</code> object, parallel process set to 5.</p>
  <pre><code>my $pm = Parallel::ForkManager-&gt;new(5);
  </code></pre>
  <p>Does this means at a time in a particular server (Ex:192.168.0.1) it should run 5 parallel process. Means it should take 5 nodes from a <code>node_list_1.txt</code> (out of 13) file and execute the command?</p>
  <p>Is my understdning correct? If not, what could be the possible solution to run the command in each server parallelly with multi-threading?</p>