我不明白为什么所有分叉的孩子都不会在Perl中使用Parallel :: ForkManager完全同时启动

Sau*_*ava 1 windows perl load-testing

我正在制作2把叉子.

我有2个案例:

  1. 我只记下每个叉子的时间
  2. 我记下每个分支中的时间,然后执行一些步骤,例如请求网站.

根据我的理解,在这两种情况下,两个孩子的开始时间差异应该在相同的范围内.但在这两种情况下,都有很多不同之处.

case1代码:

use Parallel::ForkManager;
use WWW::Mechanize;
use LWP::UserAgent;
use Time::HiRes qw/gettimeofday/;
use Time::Format qw/%time/;
use POSIX qw( strftime );
use Time::HiRes qw( gettimeofday );

$count = 2;
$pm    = new Parallel::ForkManager( $count );

for ( 1 .. $count ) {

    print "$_ ";

    my ( $secs, $microsecs ) = gettimeofday();
    print
        strftime( "%H:%M:%S", localtime( $secs ) ) .
        sprintf(".%04d", $microsecs / 10 );

    print "\n";

    $pm->finish;
}

$pm->wait_all_children;    ## wait for the child processes
Run Code Online (Sandbox Code Playgroud)

输出:

1 20:53:25.41494
2 20:53:25.65602
Run Code Online (Sandbox Code Playgroud)

所以,基本上我想用Perl做一些机械化操作,但我需要所有的孩子同时开始执行,这不是这里的情况.我需要几乎1000个孩子同时开始执行.请改进我的代码,或提供更好的方法来实现它.

ike*_*ami 5

你不创建任何子进程!在循环开始时添加以下内容:

$pm->start and next;
Run Code Online (Sandbox Code Playgroud)

您的主要关注点似乎是吞吐量(1000 req/s),而不是请求开始时.在这种情况下,您可以通过提前创建并重新使用它们来完全消除启动新工作所需的时间.这称为工作池模型,可以在此处找到一个简单的示例.(该示例使用线程,但同样的模型也可以与进程一起使用,如果这是优选的.)

现在,即使您通过重用工作程序来消除启动工作程序所需的时间,也不会给您留下太多时间来实际构建请求并处理响应.如果在8个内核中完美地传播,则每个请求只能获得8毫秒.

1000 req/s
= 1000/8 req/s on each core
= 125 req/s on each core
= 8 ms/req
Run Code Online (Sandbox Code Playgroud)

那不是很多.您可能需要优化代码.我将LWP转向Net :: Curl :: Multi.实际上,如果你使用Net :: Curl :: Multi,所有的请求应该由一个线程(主要的一个?)进行,尽管你可能仍然想要准备请求并处理工作线程中的响应.