Как использовать Perl для запуска одного и того же сценария php параллельно? - PullRequest
1 голос
/ 02 июля 2011

У меня есть скрипт php, который захватывает контент с другого сайта. Я хочу, чтобы один и тот же скрипт выполнялся одновременно, поэтому параллельно (с разными входными параметрами).

Существует функция pcntl, которую можно использовать для многопоточных процессов в php, однако в руководстве говорится, что не рекомендуется использовать ее в среде веб-сервера. Поэтому я решил не делать этого, так как мой скрипт работает на сервере.

Я решил использовать многопоточность в perl для вызова функции php. Когда я вызываю два разных php-скрипта из Perl, они выполняются одновременно, но когда я использую один и тот же php-скрипт, первый скрипт должен завершиться, прежде чем второй скрипт сможет запуститься.

Также, кажется, не имеет значения, использую ли я поток в perl или нет, потому что при использовании того же скрипта первая сессия должна завершиться, прежде чем начнется следующая. Скрипты php также выполняются одновременно без использования потоков, см. Скрипт ниже.

Любая помощь будет очень приветствоваться!

Файл ---> test.pl

<code></p>

<p>#!C:/wamp/bin/perl/bin/perl.exe</p>

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

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

<p>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 '<p>' . 
print('Got parameters >', join('<>', @InboundParameters), "<\n");}

test1.php:

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

test2.php:

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

1 Ответ

0 голосов
/ 07 февраля 2015

Существует очень реальная опасность при смешивании и сопоставлении в потоках, когда вы можете отключить все виды поведения, не относящегося к потоку.

Тем не менее, perl вполне способен работать с параллельными объектами без необходимости вызывать PHP.

например. ссылаясь на: Perl daemonize с дочерними демонами

#!/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-адресов, а затем получить его через LWP в потоке worker. Или, если вы действительно должны, вставьте туда свой PHP.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...