不要等待进程退出

时间:2020-03-06 14:45:09  来源:igfitidea点击:

我有一个PHP脚本,每分钟都会从cron作业中调用。该脚本从数据库中获取一些信息,然后使用System函数(向其传递一些参数)调用另一个PHP脚本。

这意味着我可以从这个"主要"脚本中启动多达10个脚本。我想做的是,我将调用该脚本并继续执行主脚本,也就是说,不要等待系统调用完成然后再调用下一个脚本。

如何才能做到这一点?

解决方案

使用叉子或者线程的php版本。

如果操作系统支持,则可以使用pcntl_fork()函数剥离父级不等待的子进程。但是要小心,很容易意外地创建过多的子进程,尤其是如果它们花费的时间比预期的要长!

我不确定PHP是否支持线程。在这里检查。

我认为答案将与已经为异步PHP调用提供的答案非常相似。

我们可以在后台运行它们:

system('php yourscript.php &');

我们只需要确保检查运行的进程总数即可。总而言之,这不是一个超级优雅的解决方案。相反,cron可以让一个脚本永远运行,我在想这样的事情:

<?php
while(true) {
  // do whatever needs to be done.
}
?>

小心点。不完全知道PHP是用作守护程序的。

http://php.net/pcntl_fork

它仅是* NIX,但我们可以使用PCNTL扩展来分叉脚本。

我们可能可以同时使用proc_open()stream_select()stream_set_blocking()来实现这种目的。

如果听起来很模糊,那我将在这里粘贴大量代码,这是我在最近的项目中使用的代码,该代码执行了类似的操作,但是随后感觉到它可能是阻碍而不是帮助!总而言之,代码的工作方式如下:

  • cronjob调用cronjob_wrapper.php
  • cronjob_wrapper.php创建一个新的Manager类,然后在其上调用。
  • Manager类的启动方法检查以查看有多少实例正在运行(在特定位置查找pid文件)。如果小于给定的最大实例数,则将其自身的进程ID写入pid文件,然后继续
  • Manage类创建适当的Encoder类的实例,并在其上调用exec。
  • exec方法使用proc_open,stream_select和stream_set_blocking以非阻塞方式运行系统命令(在这种情况下,运行ffmpeg可能要花相当长的时间!)
  • 当它最终运行时,它将清理其PID文件并解救。

现在,我变得模棱两可,是因为我们这里的多个实例是由cronjob处理的,而不是由PHP处理的。我正在尝试做我们正在谈论的那种事情,并且使pcntl_fork()和朋友可以很好地工作,但是最后我遇到了两个问题(如果我记得至少有一个是错误),并认为这种方法是实现同一目标的坚如磐石的方法。 YMMV。

不过,值得一看的是这些功能,我们可以通过它们实现很多功能。虽然我不认为PHP会成为首选的套接字编程语言... :)