linux worker script/queue (php)

2019-08-20 05:51发布

I need a binary/script (php) that does the following.

Start n process of X in the background and maintain the number processes.

An example:

  • n = 50
  • initially 50 processes are started
  • a process exits
  • 49 are still running
  • so 1 should be started again.

P.S.: I posted the same question on SV, which makes me probably very unpopular.

标签: php linux
6条回答
Rolldiameter
2楼-- · 2019-08-20 06:25

I would go in the direction that andres suggested. Just put something like this at the top of your pro.php file...

$this_file = __FILE__;
$final_count = 50;

$processes = `ps auwx | grep "php -f $this_file"`;
$processes = explode("\n", $processes);
if (count($processes)>$final_count+3) {
        exit;
}
//... Remaining code goes here
查看更多
仙女界的扛把子
3楼-- · 2019-08-20 06:26
Summer. ? 凉城
4楼-- · 2019-08-20 06:28

Pseudocode:

for (i=1; i<=50; i++)
  myprocess
endfor

while true
  while ( $(ps --no-headers -C myprocess|wc -l) < 50 )
    myprocess
  endwhile
endwhile

If you translate this to php and fix its flaws, it might just do what you want.

查看更多
Emotional °昔
5楼-- · 2019-08-20 06:30

Can you use the crontab linux and write to a db or file the number of current process?. If DB, the advantage is that you can use to procedure and lock the table, and write the number of process.

But to backgroun you should use & at the end of the call to script

# php-f pro.php &
查看更多
看我几分像从前
6楼-- · 2019-08-20 06:34

Here's something in Perl I have in my library (and hey, let's be honest, I'm not going to rig this up in PHP just to give you something working in that language this moment. I'm just using what I can copy / paste).

#!/usr/bin/perl
use threads;
use Thread::Queue;

my @workers;
my $num_threads = shift;
my $dbname = shift;
my $queue = new Thread::Queue;

for (0..$num_threads-1) {
        $workers[$_] = new threads(\&worker);
                print "TEST!\n";
}

while ($_ = shift @ARGV) {
        $queue->enqueue($_);
}

sub worker() {
        while ($file = $queue->dequeue) {
                system ('./4parser.pl', $dbname, $file);
        }
}

for (0..$num_threads-1) { $queue->enqueue(undef); }
for (0..$num_threads-1) { $workers[$_]->join; }

Whenever one of those systems calls finishes up, it moves on dequeing. Oh, and damn if I know hwy I did 0..$numthreads instead of the normal my $i = 0; $i < ... idiom, but I did it that way that time.

查看更多
forever°为你锁心
7楼-- · 2019-08-20 06:36

I have to solutions to propose. Both do child process reboot on exit, do child process reloading on USR1 signal, wait for the children exit on SIGTERM and so on.

The first is based on swoole php extension. It is very performant, async, non-blocking. Here's the usage example code:

<?php
use Symfony\Component\Process\PhpExecutableFinder;

require_once __DIR__.'/../vendor/autoload.php';
$phpBin = (new PhpExecutableFinder)->find();
if (false === $phpBin) {
    throw new \LogicException('Php executable could not be found');
}
$daemon = new \App\Infra\Swoole\Daemon();

$daemon->addWorker(1, $phpBin, [__DIR__ . '/console', 'quartz:scheduler', '-vvv']);

$daemon->addWorker(3, $phpBin, [__DIR__ . '/console', 'enqueue:consume', '--setup-broker', '-vvv']);

$daemon->run();

The daemon code is here

Another is based on Symfony process library. It does not require any extra extensions. The usage example and daemon code could be found here

查看更多
登录 后发表回答