如何使用perl运行相同的PHP脚本并行?

时间:2011-07-02 12:27:00

标签: php multithreading perl

我有一个PHP脚本,可以抓取另一个网站的内容。我希望同一个脚本同时运行,所以并行(使用不同的输入参数)。

有一个函数pcntl可以用于php中的多线程进程,但是手册说它不建议在Web服务器环境中使用它。所以我决定不这样做,因为我的脚本在服务器上运行。

我决定在perl中使用线程来调用php函数。当我从Perl调用两个不同的php脚本时,它们会同时执行,但是当我使用相同的php脚本时,第一个脚本必须在第二个脚本启动之前完成。

如果我在perl中使用线程,似乎没有任何区别,因为当使用相同的脚本时,第一个会话必须在它开始下一个之前完成。 php脚本也可以在不使用线程的情况下同时执行,请参阅下面的脚本。

非常欢迎任何帮助!

文件---> test.pl

#!C:/wamp/bin/perl/bin/perl.exe

print "Content-type: text/html\n\n"; print '' . "\n

"; print '' . "\n

";

use Config; $Config{useithreads} or die('Recompile Perl with threads to run this program.');

use threads; my $Param3 = 'foo'; my $thr1 = threads->create(\&sub1, 'Param 1', 'Param 2', $Param3); my @ParamList = (42, 'Hello', 3.14); my $thr2 = threads->create(\&sub1, @ParamList); my $thr3 = threads->create(\&sub1, qw(Param1 Param2 Param3)); sub sub1 { my @InboundParameters = @_; print("In the thread\n"); print '

' . print('Got parameters >', join('<>', @InboundParameters), "<\n");}

test1.php:

<?php echo "PHP generated this, this is script test1"; sleep(5); ?>

test2.php:

<?php echo "PHP generated this, this is script test2"; sleep(5);?></pre></code>

1 个答案:

答案 0 :(得分:0)

在线程中混合和匹配时存在非常真实的危险,在这种情况下,您可以跳过各种“非线程安全”行为。

但是,perl完全能够处理并行内容,而无需“调用”PHP。

E.g。参考:Perl daemonize with child daemons

#!/usr/bin/perl

use strict;
use warnings;

use threads;
use Thread::Queue;

my $nthreads = 5;

my $process_q = Thread::Queue->new();
my $failed_q  = Thread::Queue->new();

#this is a subroutine, but that runs 'as a thread'.
#when it starts, it inherits the program state 'as is'. E.g.
#the variable declarations above all apply - but changes to
#values within the program are 'thread local' unless the
#variable is defined as 'shared'.
#Behind the scenes - Thread::Queue are 'shared' arrays.

sub worker {

    #NB - this will sit a loop indefinitely, until you close the queue.
    #using $process_q -> end
    #we do this once we've queued all the things we want to process
    #and the sub completes and exits neatly.
    #however if you _don't_ end it, this will sit waiting forever.
    while ( my $server = $process_q->dequeue() ) {
        chomp($server);
        print threads->self()->tid() . ": pinging $server\n";
        my $result = `/bin/ping -c 1 $server`;
        if ($?) { $failed_q->enqueue($server) }
        print $result;
    }
}

#insert tasks into thread queue.
open( my $input_fh, "<", "server_list" ) or die $!;
$process_q->enqueue(<$input_fh>);
close($input_fh);

#we 'end' process_q  - when we do, no more items may be inserted,
#and 'dequeue' returns 'undefined' when the queue is emptied.
#this means our worker threads (in their 'while' loop) will then exit.
$process_q->end();

#start some threads
for ( 1 .. $nthreads ) {
    threads->create( \&worker );
}

#Wait for threads to all finish processing.
foreach my $thr ( threads->list() ) {
    $thr->join();
}

#collate results. ('synchronise' operation)
while ( my $server = $failed_q->dequeue_nb() ) {
    print "$server failed to ping\n";
}

你可以通过这样做看到 - 你可以'排队'一个URL列表,然后通过worker线程中的LWP获取它。或者如果您真的必须,那么将PHP嵌入其中。