这是我的调度程序的实现,我只需要在不活动时启动它并在 mysql 作业表上添加所有作业(我的主脚本已经有一个),这个脚本将启动所有准备好的作业被执行(sql表有一个日期时间字段)。
我所说的“互斥锁”是一个类,它告诉脚本的一个或多个副本是否正在运行,甚至可以通过管道向正在运行的脚本发送命令(您只需创建一个具有相同所有脚本的名称),因此您甚至可以从另一个脚本停止正在运行的脚本。
<?php
//---logging---
$logfile = dirname(dirname(__FILE__)).'/scheduler.log';
$ob_file = fopen($logfile,'a');
function ob_file_callback($buffer)
{
global $ob_file;
fwrite($ob_file,$buffer);
}
//--includes---
$inc=dirname(dirname(__FILE__)).'/.include/';
require_once($inc.'Mutex.php');
require_once($inc.'jobdb.php');
//--mutex---
//i call it mutex but it's nothing like POSIX mutex,it's a way to synchronyze scripts
$m=new Mutex('jscheduler');
if(!$m->lock())//if this script is already running
exit();//only one scheduler at time
//---check loop---
set_time_limit(-1);//remove script time limit
for(;;){
ob_start('ob_file_callback');//logging
$j=jobdb_get_ready_jobs(true);//gets all ready jobs,works with mysql
if($j!=null)//found some jobs
foreach($j as $val){//run all jobs
$ex='*SCRIPT NAME AND PARAMETERS HERE*';
if(!run_script($ex))
echo "UNABLE TO LAUNCH THE JOB!\n";
}
$n=($j!=null)?count($j).'JOBS LAUNCHED':'NO JOBS';
sleep(60);
if($m->has_to_stop())//yeah,i can stop this script from other scripts,it works with a file pipeline
exit("# STOPPING SCHEDULER\n");
ob_end_flush();//LOGGING
}
?>
我的“run_script”函数与 Sciberras“run”函数的工作方式相同。
要激活调度程序,您只需使用此命令
run_script('scheduler.php');
检查它是否处于活动状态
$m=new Mutex('jscheduler');
if(!$m->test_lock())
echo 'SCHEDULER IS ACTIVE';
else
echo 'SCHEDULER IS INACTIVE';
并停止调度程序
$m=new Mutex('jscheduler');
$m->ask_to_stop();//simply sent throught the pipe the command,now has_to_stop()will return true on the process that have gain the lock of the mutex
echo 'STOPPING SCHEDULER...';
我可能在他的实现上走得太远了,无论如何可能存在“滞后”问题,例如,如果调度程序从 0:00.00 开始,而我在 0:01.01 和 0:01.59 有两个脚本都是于 0:02.0 启动。
为了解决这个“滞后”,我可能会检索下一分钟安排的所有作业,并使用 time_sleep_until 在 Sciberras 代码中安排它们。
这不会创建太多正在运行的线程(我可能想测试在启动大量线程时是否存在限制或性能下降,但我相信会有一些问题)并确保完美的时间安排只需要检查是否调度程序处于活动状态。