Frage

I have a PHP script to run a command with execute time limit and cpu time limit.

limit.php :

<?php
declare(ticks = 1);
ini_set('display_errors','on');
error_reporting(E_ALL);

if ($argc<2) die("Usage: php ".__FILE__." \"your command here\" [execute_time_limit = 600] [cpu_time_limit = 120]\n");
$cmd = $argv[1];
$tl = isset($argv[2]) ? intval($argv[2]) : 0;
$cl = isset($argv[3]) ? intval($argv[3]) : 0;
if (!$cmd) die("INCORRECT_CMD");
if ($tl<=0) $tl = 600;
if ($cl<=0) $cl = 120;

function sigalrm_handler($signo) {die('EXECUTE_ENDED');}//normal ended or killed by ulimit

$pid = pcntl_fork();
if (-1 == $pid) {
    die('FORK_FAILED');
} elseif ($pid == 0) {
    exec("ulimit -t $cl && $cmd");
    posix_kill(posix_getppid(), SIGALRM);
} else {
    pcntl_signal(SIGALRM, 'sigalrm_handler');
    sleep($tl);
    posix_kill($pid, SIGKILL);
    die("TIMEOUT_KILLED : $pid");
}

Another PHP script for test.

test.php

<?php
$i=0;
echo getmypid();
while(1) {
    $i++;
    file_put_contents("/tmp/x.log",$i."\n",FILE_APPEND);
    echo "*";
    sleep(1);
}

Run this command:

php limit.php "php test.php" 10

Use "ps -ef|grep ph[p]", you can find processes forked and killed as we expected.

But when I try this command,

php limit.php "php test.php > /tmp/y.log" 10

the children processes cannot be killed as we expected. See:

Begining:

===============

alix     28979 23528  0 17:32 pts/0    00:00:00 php limit.php php test.php > /tmp/y.log 10
alix     28980 28979  0 17:32 pts/0    00:00:00 php limit.php php test.php > /tmp/y.log 10
alix     28981 28980  0 17:32 pts/0    00:00:00 sh -c ulimit -t 120 && php test.php > /tmp/y.log
alix     28982 28981  0 17:32 pts/0    00:00:00 php test.php

after 10s:

=================

alix     28981     1  0 17:32 pts/0    00:00:00 sh -c ulimit -t 120 && php test.php > /tmp/y.log
alix     28982 28981  0 17:32 pts/0    00:00:00 php test.php

PID 28979 forked 28980, then function exec created 2 children process with PID 28981 and 28982. 10s later, 28979 send SIGKILL to 28980, but 28981 and 28982 were not impacted (they will be killed if there is not output redirect like "> /tmp/y.log").

My server is : Linux s4 2.6.18-308.1.1.el5 #1 SMP Wed Mar 7 04:16:51 EST 2012 x86_64 x86_64 x86_64 GNU/Linux With PHP 5.3.9 (cli) (built: Feb 15 2012 11:54:46)

Any suggestion?

War es hilfreich?

Lösung

The reason is PIPE. Check the answer in another question of mine:

standard output impact SIGKILL?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top