我有一個PHP腳本來運行帶有執行時間限制和cpu時間限制的命令。輸出重定向時不能終止子進程
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");
}
測試另一個PHP腳本。
test.php的
<?php
$i=0;
echo getmypid();
while(1) {
$i++;
file_put_contents("/tmp/x.log",$i."\n",FILE_APPEND);
echo "*";
sleep(1);
}
運行以下命令:
PHP limit.php 「PHP test.php的」 10
使用「ps的英法| grep的PH [ p]「,你可以按照我們的預期找到分叉和死亡的進程。
但當我嘗試這個命令,
PHP limit.php 「PHP test.php的> /tmp/y.log」 如我們預期10個
孩子進程不能被殺死。請參閱:
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
後10秒:
========= ========
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 28980分叉,那麼函數EXEC創建2個孩子的過程與PID 28981和28982. 10秒後,28979發送SIGKILL至28980,但28981一nd 28982沒有受到影響(如果沒有輸出重定向,如「> /tmp/y.log」,它們將被殺死)。
我的服務器是: Linux的S4 2.6.18-308.1.1.el5#1 SMP週三03月07日4時16分51秒美國東部時間2012 x86_64的x86_64的x86_64的GNU/Linux的 隨着PHP 5.3.9(CLI)(建:Feb 15 2012 11:54:46)
有什麼建議嗎?
不應該有之間** ** test.php的,**> **和**的/ tmp/y.log空間**? ? – 2012-08-09 10:00:53
@ Dr.Dan謝謝。但沒有區別。 – Alix 2012-08-09 10:05:20