| 本帖最后由 ziwu85 于 2009-11-7 19:39 编辑 
 现象:
 今天自己做了个计划任务,但是狂按立即执行,程序好像就是没有被执行的样子。
 
 原因:
 没办法只能自己分析程序,为什么不执行了。
 一看程序才明白,原来S_ROOT.'./log/cron.lock.log'存在时,5分钟内禁止再执行任何计划任务了。
 到相应位置一看,果然cron.lock.log存在。
 可这个cron.lock.log又是怎么出来的呢?原来是在计划任务执行之前程序先要自动生成cron.lock.log,且在全部计划任务执行完毕再删除它(@unlink($lockfile);)。
 而,我新写的计划任务有问题,执行了一半就停止了。导致cron.lock.log没有被自动删除掉。结果我5分钟内,拼命按立即执行我的代码也执行不到了。
 另外,cron.lock.log的存在,不仅影响立即执行的功能,同样在这5分钟内自动执行的计划任务,也不会被执行了。
   
 解决方法:
 手工删除cron.lock.log文件后,再按立即执行就好使了。
 
 评语:
 这也许是康盛创想防止计划任务二次执行的一种手段。但,是否还能有更好的实现方法呢?或者说5分钟以后,计划任务还没有完成,是不是就能被二次执行了呢?
 不知道官方是什么看法?
 
 下面是ss7.0计划任务执行的核心函数的原版代码,给大家参考。
 复制代码//执行计划任务,并更新计划任务CACHE
function runcron($cronid = 0) {
        global $_SGLOBAL, $_SCONFIG, $_SBLOCK, $lang;
        //锁定
        $lockfile = S_ROOT.'./log/cron.lock.log';
        if(file_exists($lockfile)) {
                if($_SGLOBAL['timestamp'] - filemtime($lockfile) < 300) {//5分钟
                        return;
                }
        }
        if(@$fp = fopen($lockfile, 'w')) {
                fwrite($fp, "\n");
                fclose($fp);
        }
        //读取cron列表缓存
        if(empty($_SGLOBAL['crons'])) return;
        @set_time_limit(1000);
        @ignore_user_abort(TRUE);
        $cronids = array();
        $crons = $cronid ? array($cronid => $_SGLOBAL['crons'][$cronid]) : $_SGLOBAL['crons'];
        if(empty($crons) || !is_array($crons)) return;
        foreach($crons as $id => $cron) {
                if($cron['nextrun'] <= $_SGLOBAL['timestamp'] || $id == $cronid) {
                        $cronids[] = $id;
                        if(!@include S_ROOT.($cronfile = "./include/cron/$cron[filename]")) {
                                errorlog('CRON', $cron['name']." : Cron script($cronfile) not found or syntax error", 0);
                        }
                }
        }
        cronnextrun($cronids);
        @unlink($lockfile);
}
 |