我知道这是一个古老的线程,但看起来像它可以使用一个更完整的答案。这是我通常在PHP中产生多个进程的方式。
谨慎的一句话:PHP was meant to die.意思是说,语言意味着要执行几秒钟然后退出。尽管PHP中的垃圾清理已经走过了很长的路,但要小心。监视您的进程,以发现意外的内存消耗或其他异常情况。在你设置并忘记它之前,一切都像鹰一样观看,即使如此,仍然会偶尔检查一下流程,或者在出现问题时自动通知它们。
当我打字的时候,看起来像是一个好主意,拍到github。
当准备运行该程序时,我建议在日志上做一个尾部-f来查看输出。
<?php
/*
* date: 27-sep-2015
* auth: robert smith
* info: run a php daemon process
* lic : MIT License (see LICENSE.txt for details)
*/
$pwd = realpath("");
$daemon = array(
"log" => $pwd."/service.log",
"errorLog" => $pwd."/service.error.log",
"pid_file" => $pwd."/",
"pid" => "",
"stdout" => NULL,
"stderr" => NULL,
"callback" => array("myProcessA", "myProcessB")
);
/*
* main (spawn new process)
*/
foreach ($daemon["callback"] as $k => &$v)
{
$pid = pcntl_fork();
if ($pid < 0)
exit("fork failed: unable to fork\n");
if ($pid == 0)
spawnChores($daemon, $v);
}
exit("fork succeeded, spawning process\n");
/*
* end main
*/
/*
* functions
*/
function spawnChores(&$daemon, &$callback)
{
// become own session
$sid = posix_setsid();
if ($sid < 0)
exit("fork failed: unable to become a session leader\n");
// set working directory as root (so files & dirs are not locked because of process)
chdir("/");
// close open parent file descriptors system STDIN, STDOUT, STDERR
fclose(STDIN);
fclose(STDOUT);
fclose(STDERR);
// setup custom file descriptors
$daemon["stdout"] = fopen($daemon["log"], "ab");
$daemon["stderr"] = fopen($daemon["errorLog"], "ab");
// publish pid
$daemon["pid"] = sprintf("%d", getmypid());
file_put_contents($daemon["pid_file"].$callback.".pid", $daemon["pid"]."\n");
// publish start message to log
fprintf($daemon["stdout"], "%s daemon %s started with pid %s\n", date("Y-M-d H:i:s"), $callback, $daemon["pid"]);
call_user_func($callback, $daemon);
// publish finish message to log
fprintf($daemon["stdout"], "%s daemon %s terminated with pid %s\n", date("Y-M-d H:i:s"), $callback, $daemon["pid"]);
exit(0);
}
function myProcessA(&$daemon)
{
$run_for_seconds = 30;
for($i=0; $i<$run_for_seconds; $i++)
{
fprintf($daemon["stdout"], "Just being a process, %s, for %d more seconds\n", __FUNCTION__, $run_for_seconds - $i);
sleep(1);
}
}
function myProcessB(&$daemon)
{
$run_for_seconds = 30;
for($i=0; $i<$run_for_seconds; $i++)
{
fprintf($daemon["stdout"], "Just being a process, %s, for %d/%d seconds\n", __FUNCTION__, $i, $run_for_seconds);
sleep(1);
}
}
?>
这种事情并不是真的是PHP的目标或擅长。分叉过程比产卵线程昂贵得多,这就是典型的做法。 – cletus 2010-01-06 23:57:40
我可以用线程轻松地在Python中完成这件事,但出于具体原因,PHP是唯一可用的选项。 – mmattax 2010-01-07 00:16:01
那么Python有多线程代码的问题,最显着的是CPython上的GIL。 Jython/IronPython没有这个问题,但我想需要编译。 – cletus 2010-01-07 08:55:04