Bellow là thực hiện làm việc của chúng ta về câu trả lời @chaos. Mã để xử lý tín hiệu đã bị xóa vì tập lệnh này thường chỉ mất vài phần nghìn giây.
Ngoài ra, trong mã, chúng tôi đã thêm 2 chức năng để tiết kiệm pids giữa các cuộc gọi: restore_processors_state() và save_processors_state(). Chúng tôi đã sử dụng redis
ở đó, nhưng bạn có thể quyết định sử dụng triển khai trên các tệp.
Chúng tôi chạy tập lệnh này mỗi phút bằng cách sử dụng cron. Cron kiểm tra xem tất cả các tiến trình có còn sống hay không. Nếu không - nó chạy lại chúng và sau đó chết. Nếu chúng ta muốn giết các tiến trình hiện có thì chúng ta chỉ cần chạy tập lệnh này với đối số kill
: php script.php kill
.
Cách tiện dụng để chạy công nhân mà không cần tiêm tập lệnh vào init.d.
<?php
include_once dirname(__FILE__) . '/path/to/bootstrap.php';
define('WANT_PROCESSORS', 5);
define('PROCESSOR_EXECUTABLE', '' . dirname(__FILE__) . '/path/to/worker.php');
set_time_limit(0);
$run = true;
$reload = false;
declare(ticks = 30);
function restore_processors_state()
{
global $processors;
$redis = Zend_Registry::get('redis');
$pids = $redis->hget('worker_procs', 'pids');
if(!$pids)
{
$processors = array();
}
else
{
$processors = json_decode($pids, true);
}
}
function save_processors_state()
{
global $processors;
$redis = Zend_Registry::get('redis');
$redis->hset('worker_procs', 'pids', json_encode($processors));
}
function spawn_processor() {
$pid = pcntl_fork();
if($pid) {
global $processors;
$processors[] = $pid;
} else {
if(posix_setsid() == -1)
die("Forked process could not detach from terminal\n");
fclose(STDIN);
fclose(STDOUT);
fclose(STDERR);
pcntl_exec('/usr/bin/php', array(PROCESSOR_EXECUTABLE));
die('Failed to fork ' . PROCESSOR_EXECUTABLE . "\n");
}
}
function spawn_processors() {
restore_processors_state();
check_processors();
save_processors_state();
}
function kill_processors() {
global $processors;
foreach($processors as $processor)
posix_kill($processor, SIGTERM);
foreach($processors as $processor)
pcntl_waitpid($processor, $trash);
unset($processors);
}
function check_processors() {
global $processors;
$valid = array();
foreach($processors as $processor) {
pcntl_waitpid($processor, $status, WNOHANG);
if(posix_getsid($processor))
$valid[] = $processor;
}
$processors = $valid;
if(count($processors) > WANT_PROCESSORS) {
for($ix = count($processors) - 1; $ix >= WANT_PROCESSORS; $ix--)
posix_kill($processors[$ix], SIGTERM);
for($ix = count($processors) - 1; $ix >= WANT_PROCESSORS; $ix--)
pcntl_waitpid($processors[$ix], $trash);
}
elseif(count($processors) < WANT_PROCESSORS) {
for($ix = count($processors); $ix < WANT_PROCESSORS; $ix++)
spawn_processor();
}
}
if(isset($argv) && count($argv) > 1) {
if($argv[1] == 'kill') {
restore_processors_state();
kill_processors();
save_processors_state();
exit(0);
}
}
spawn_processors();
Nguồn
2013-11-18 08:19:06
Xem thêm: http://symfony.com/doc/master/components/process.html –