我目前在CMS应用程序中处理计划任务(如cronjobs)系统。我想知道当一段代码的执行时间超过指定的时间限制时是否有可能终止它。
某些计划任务可能很重,任务可能会遇到无限循环,以保持简短;任务占用大量时间的原因很多。这方面的一个问题是,任务将占用比实际需要更多的资源,这会降低其运行的服务器的性能,这将使CMS和站点自身不太可靠。 / p>
将系统想象如下:一旦触发了计划任务管理器,它将执行那个时间安排的所有任务。想象一个简单的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语句在每个计划任务的代码中实现此功能,该语句在每次执行代码的一部分时检查时间。这个问题是需要在每个任务的代码中实现,因为该系统旨在用于第三方开发人员正确使用这些任务来实现这些任务的插件。我不想强迫'所有使用任务来实现此类功能的开发人员。
我知道PHP提供的set_time_limit();
方法,问题是这个方法会终止整个会话而不是那个方法,这就是为什么这并不能解决问题。
答案 0 :(得分:2)
如果超过时间,你可以打破循环:
$max = 1000; //maximum time in milliseconds
$start = microtime(true);
foreach($tasks as $t) {
// Execute the task
$t->execute();
if (microtime(true) - $start > $max) {
break;
}
}
答案 1 :(得分:2)
我遇到过这种问题,我有一个可以解决这个问题的技巧。我的解决方法是,我使用cURL执行本地脚本,如下所示:
// This is the curl call which will execute the local script
$execute_script = curl_call('local_script.php');
在' local_script.php' file是要执行的代码
// In local_script.php
// Set time limit
set_time_limit(10);
// Execute task
$task->execute();
// Print 1 to let the curl call know that the script executed at the right time
echo '1';
然后,在cURL调用部分中,您可以检查脚本在返回时是否正常执行" 1"
if ($execute_script == '1'){
// Successful script
} else {
// Timed out
}
希望有所帮助
答案 2 :(得分:2)
将我的评论“移植”到答案:
This other question非常相似。
PHP,通过其默认实现,在单个线程中运行脚本,因此不可能从脚本本身取消代码执行。
只有非常非常的PHP函数支持异步操作,例如您可以使用mysqlnd
运行异步查询,但是这个特殊功能是mysql驱动程序的一部分,而不是PHP。
有一些扩展将PHP引入多线程,即pthread。
要推荐其他来源,请阅读扩展程序作者的this answer。
不幸的是,对于一个“主流”项目(尽可能以通用设置运行),使用pthreads
是不可行的。
该扩展程序不太可能安装在任何共享的网站空间上。
另外,请记住,线程安全编程(或者脚本适用于那些关心的人)是一项严肃的任务,您必须关心它。这意味着准备您的线程代码不会锁定彼此等待(死锁),损坏彼此的数据等。
有关线程安全一词的详细答案可以找到here。
彻底考虑所涉及的工作,弄乱某些事情的风险以及使用线程的好处 确保您的愿望非常重要,足以引入复杂的线程。