不用crontab实现php 原生代码执行定时任务

PHP 专栏收录该内容
101 篇文章 0 订阅
<?php

/***
 * 不用crontab实现php 原生代码执行定时任务
 * /usr/local/php/bin/php test.php
 * Class Timer
 */
class Timer extends SplMinHeap
{
    /**
     * 比较根节点和新插入节点大小
     * @param mixed $value1
     * @param mixed $value2
     * @return int
     */
    protected function compare($value1, $value2)
    {
        if ($value1['timeout'] > $value2['timeout']) {
            return -1;
        }
        if ($value1['timeout'] < $value2['timeout']) {
            return 1;
        }
        return 0;
    }

    /**
     * 插入节点
     * @param mixed $value
     */
    public function insert($value)
    {
        $value['timeout'] = time() + $value['expire'];
        parent::insert($value);
    }

    /**
     * 监听
     * @param bool $debug
     */
    public function monitor($debug = false)
    {
        while (!$this->isEmpty()) {
            $this->exec($debug);
            usleep(1000);
        }
    }

    /**
     * 执行
     * @param $debug
     */
    private function exec($debug)
    {
        $hit = 0;
        $t1 = microtime(true);
        while (!$this->isEmpty()) {
            $node = $this->top();
            if ($node['timeout'] <= time()) {
//出堆或入堆
                $node['repeat'] ? $this->insert($this->extract()) : $this->extract();
                $hit = 1;
//开启子进程
                if (pcntl_fork() == 0) {
                    empty($node['action']) ? '' : call_user_func($node['action']);
                    exit(0);
                }
//忽略子进程,子进程退出由系统回收
                pcntl_signal(SIGCLD, SIG_IGN);
            } else {
                break;
            }
        }
        $t2 = microtime(true);
        echo ($debug && $hit) ? '时间堆 - 调整耗时: ' . round($t2 - $t1, 3) . "秒\r\n" : '';
    }
}

$timer = new Timer();

//注册 - 3s - 重复触发
$timer->insert(
    array(
        'expire' => 3,
        'repeat' => true,
        'action' => function () {
            echo '3秒 - 重复 - gogo' . "\r\n";
        }
    )
);
//注册 - 6s - 触发一次
$timer->insert(
    array(
        'expire' => 6,
        'repeat' => false,
        'action' => function () {
            echo '6秒 - 一次 - hello xxxx' . "\r\n";
        }
    )
);
//监听
$timer->monitor(true);
  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值