我目前正在CMS应用程序中处理计划任务(如cronjobs)系统.我想知道当执行时间超过指定的时间限制时是否有可能终止一段代码.
某些计划任务可能很重,任务可能会进入无限循环,以保持简短;任务占用大量时间的原因很多.这方面的一个问题是,任务将占用比实际需要更多的资源,这会降低运行它的服务器的性能,这会使CMS和站点自身不太可靠.
将系统想象如下:一旦触发了计划任务管理器,它将执行那个时间安排的所有任务.想象一个简单的for循环,它将执行每个任务,一个接一个地同步.想想下面这个简单的例子:
// This array would contain an array with all scheduled tasks that should be executed.
$tasks = Array();
// Loop through each task
foreach($tasks as $t) {
// Execute the task
$t->execute();
}
现在,$task-> execute();方法使PHP的解释器等到任务的代码执行.我的问题是,是否有任何可能的方法来终止在execute()后面运行的代码;方法,如果它的执行时间超过指定的时间.
例如,如果提供了10秒的时间限制,并且任务执行代码的时间超过30秒,则任务的运行代码应在10秒后终止,以允许任务调度程序继续执行下一个任务.
可以使用简单的if语句在每个计划任务的代码中实现此功能,该语句在每次执行代码的一部分时检查时间.这个问题是需要在每个任务的代码中实现,因为该系统旨在用于第三方开发人员正确使用这些任务来实现这些任务的插件.我不喜欢“强迫”所有使用这些任务的开发人员来实现这些功能.
我知道set_time_limit();方法PHP提供,问题是虽然这个方法会终止整个会话而不是那个方法,这就是为什么这不能解决问题.
解决方法:
将我的评论“移植”到答案:
This other question非常相似.
PHP的默认实现在单个线程中运行脚本,因此无法从脚本本身取消代码执行.
只有极少数PHP函数支持异步操作,例如你可以使用MysqLnd运行异步查询,但是这个特殊功能是MysqL驱动程序的一部分,而不是PHP.
有一些扩展引入了PHP的多线程,即pthread.
要推荐其他来源,请阅读扩展名作者的this answer.
不幸的是,对于一个“主流”项目(应尽可能在通用设置上运行),使用pthreads是不可行的.
该扩展名不太可能安装在任何共享的网站空间上.
另外,请记住,线程安全编程(或者为那些关心的人编写脚本)是一项严肃的任务,您必须关心它.这意味着准备你的线程代码不会锁定彼此等待(死锁),破坏彼此的数据等.
有关线程安全术语的详细答案可以在here找到.
彻底考虑所涉及的工作,搞乱某些事情的风险,以及使用线程的好处.
确保您的愿望非常重要,足以引入复杂的线程.