我知道這是一個古老的線程,但看起來像它可以使用一個更完整的答案。這是我通常在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