2008-09-25 88 views
1

我有一个每分钟从一个cron作业调用的PHP脚本。该脚本从数据库中获取一些信息,然后使用System函数调用另一个PHP脚本(传递一些参数)。不要等待进程退出

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

这怎么办?

回答

3

您或许可以使用proc_open(),stream_select()stream_set_blocking()来实现这样的事情。

如果这听起来含糊不清,我会在这里粘贴一大块代码,我在最近的一个项目中使用了类似的东西,但后来觉得它可能会阻碍而不是帮助!综上所述,虽然,代码工作就像这样:

  1. 的cronjob cronjob_wrapper.php调用
  2. cronjob_wrapper.php创建一个新的管理类,然后调用它开始
  3. Manager类的启动方法检查以查看有多少实例正在运行(查找特定位置中的pid文件)。如果它小于给定的最大数量的实例,它会将它自己的进程ID写入一个pid文件,然后进行
  4. 管理类创建适当的编码器类的实例,并调用exec
  5. exec方法使用proc_open,stream_select和stream_set_blocking以非阻塞的方式运行系统命令(在这种情况下运行ffmpeg - 可能需要相当长的一段时间!)
  6. 当它终于运行时,清理它的PID文件并保留。

现在,我被模糊和handwavy的原因是我们这里的多个实例正在由cronjob而不是由PHP处理。我试图做很多你正在谈论的事情,并得到了与pcntl_fork()和朋友很好的工作,但最终我遇到了一些问题(如果我记得至少有一个是PHP中的错误)并决定这种方法是实现同样目标的更坚定的方法。因人而异。

虽然值得看看这些功能,但可以与他们取得很多成就。虽然不知何故,我不认为PHP将成为选择的插座编程语言... :)

+0

在action中看到stream_select()我有一个库可以发出非阻塞http请求(想一想ping),看看这里:http://drupal.org/project/httprl。它适用于Drupal,但只需进行一些微小的更改就可以自行运行。 – mikeytown2 2012-02-22 01:03:55

-1

使用php的fork或线程版本。

+0

PHP不支持线程,但fork()在这里是一个可接受的选项。 – Rob 2008-09-25 22:04:54

1

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

0

我不确定PHP是否支持线程。检查here

-1

你可以在后台运行它们:

system('php yourscript.php &'); 

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

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

虽然小心。 PHP并不完全知道被用作守护进程。

+3

不适用于我。这个脚本`<?php system(“sleep 5 &"); echo”Test“;?>`在编写测试消息前还睡5秒 – Gart 2010-07-07 12:40:49