我正在创建一个将通过命令行运行的PHP脚本。作为此脚本的一部分,有时我可能需要生成/分叉可能需要很长时间才能完成的不同脚本。我不想阻止原始脚本完成。如果我使用JavaScript执行此操作,我可以在后台运行AJAX请求。这基本上就是我在这里要做的。我不需要知道叉子什么时候完成,只需要开始并完成自己。
如何异步运行这些PHP脚本?
foreach ($lotsOfItems as $item) {
if ($item->needsExtraHelp) {
//start some asynchronous process here, and pass it $item
}
}
答案 0 :(得分:3)
$pids = array();
foreach ($lotsOfItems as $item) {
if ($item->needsExtraHelp) {
$pid = pcntl_fork();
if ($pid == 0) {
// you're in the child
var_dump($item);
exit(0); // don't forget this one!!
} else if ($pid == -1) {
// failed to fork process
} else {
// you're in the parent
$pids[] = $pid;
}
}
usleep(100); // prevent CPU from peaking
foreach ($pids as $pid) {
pcntl_waitpid($pid, $exitcode, WNOHANG); // prevents zombie processes
}
}
答案 1 :(得分:2)
int pcntl_fork ( void )
pcntl_fork()函数创建的子进程仅在其PID和PPID中与父进程不同。有关fork如何在系统上运行的具体细节,请参见系统的fork(2)手册页。
详细信息:http://php.net/manual/en/function.pcntl-fork.php
相关问题:PHP: What does pcntl_fork() really do?
不应在Web服务器环境中启用过程控制,并且如果在Web服务器环境中使用任何过程控制功能,则可能会发生意外结果。
答案 2 :(得分:2)
查看用户在exec上提供的注释,看起来您可以使用它,请查看:
http://de3.php.net/manual/en/function.exec.php#86329
<?php function execInBackground($cmd) { if (substr(php_uname(), 0, 7) == "Windows"){ pclose(popen("start /B ". $cmd, "r")); } else { exec($cmd . " > /dev/null &"); } } ?>
这将执行$ cmd 没有PHP的背景(没有cmd窗口) 两个都在等待它完成 Windows和Unix。