代码之家  ›  专栏  ›  技术社区  ›  joe

如何在parallel::forkmanager中获取子进程ID?

  •  -1
  • joe  · 技术社区  · 15 年前
      use LWP::Simple;
      use Parallel::ForkManager;
    
    
      @links=( 
        ["http://prdownloads.sourceforge.net/sweethome3d/SweetHome3D-2.1-windows.exe","SweetHome3D-2.1-windows.exe"], 
        ["http://prdownloads.sourceforge.net/sweethome3d/SweetHome3D-2.1-macosx.dmg","SweetHome3D-2.1-macosx.dmg"],
        ["http://prdownloads.sourceforge.net/sweethome3d/SweetHome3DViewer-2.1.zip","SweetHome3DViewer-2.1.zip"],
    
      );
    
      # Max 30 processes for parallel download
      my $pm = new Parallel::ForkManager(30); 
    
      foreach my $linkarray (@links) {
        my $pid = $pm->start and next; # do the fork
    
        my ($link,$fn) = @$linkarray;
        warn "Cannot get $fn from $link"
          if getstore($link,$fn) != RC_OK;
    
        print "$pid = $link is done ";
    
        $pm->finish; # do the exit in the child process
      }
      $pm->wait_all_children;
    

    执行完之后,我的PID为零

    0 = http://prdownloads.sourceforge.net/sweethome3d/SweetHome3DViewer-2.1.zip is done 
    
    0 = http://prdownloads.sourceforge.net/sweethome3d/SweetHome3D-2.1-macosx.dmg is done 
    
    0 = http://prdownloads.sourceforge.net/sweethome3d/SweetHome3D-2.1-windows.exe is done
    

    但现在我真的在想它是否真的在做叉子。为什么我在parallel::forkmanager中一直得到0作为pid?

    编辑2

    我有两个零钱

    my $pid = $pm->start ; # do the fork
    

    $$ 用于进程ID

    21892 = http://prdownloads.sourceforge.net/sweethome3d/SweetHome3D-2.1-windows.exe is done 
    
    21893 = http://prdownloads.sourceforge.net/sweethome3d/SweetHome3D-2.1-windows.exe is done 
    
    21892 = http://prdownloads.sourceforge.net/sweethome3d/SweetHome3D-2.1-macosx.dmg is done 
    
    23120 = http://prdownloads.sourceforge.net/sweethome3d/SweetHome3D-2.1-macosx.dmg is done 
    
    21892 = http://prdownloads.sourceforge.net/sweethome3d/SweetHome3DViewer-2.1.zip is done 
    
    23146 = http://prdownloads.sourceforge.net/sweethome3d/SweetHome3DViewer-2.1.zip is done 
    

    但现在我有两次。我为什么要买这个?

    4 回复  |  直到 10 年前
        1
  •  5
  •   Nic Strong    15 年前

    不确定Parallel::ForkManager实现,但如果它与标准fork()类似,则返回0,因为您在子进程中。fork将只向父进程返回非零PID。

    我忘了添加,因为在开始调用之后有了“和下一个”,代码的行为与预期完全一致。

    注意编辑2:

    由于从开始调用中删除了“and next”,父进程也在运行下载。我猜21892是父进程的PID,它将在循环中运行多次

        2
  •  5
  •   edgar.holleis    15 年前

    关于您在edit2下的代码:

    你改变了

    my $pid = $pm->start and next;
    

    my $pid = $pm->start ; # do the fork
    

    现在你的叉子做得不正确。以前只有子进程继续执行循环体,父进程接受 下一个 ,现在两者都继续执行循环体。因此,您会看到父级(21892)的PID多次执行循环。

        3
  •  4
  •   innaM    15 年前

    看到那条线了吗?

    my $pid = $pm->start and next; # do the fork
    

    父级获取PID,子级将只看到0。如果要从子进程中获取PID,只需使用magic变量 $$ .

    更新:

    对该行的引用并不意味着邀请更改该行。但是看看它,很明显$pid在后面的代码中将是0,所以它不应该让人惊讶 print $pid 将打印 0 没有别的了。

        4
  •  0
  •   rajeev    10 年前
    forloop{
    if (my $pid = $pm->start($linkarray)){
                  print "pid-i-got-from-child=$pid and this code is running under pid=$$\n";
                  next;
                }
    ... and then continue with code processing in child process...
    
    }
    

    这将为您提供子PID,并继续使用fork处理代码。