177 lines
4.0 KiB
PHP
177 lines
4.0 KiB
PHP
<?php
|
||
namespace Workerman\Lib;
|
||
use \Workerman\Events\EventInterface;
|
||
use \Exception;
|
||
|
||
/**
|
||
*
|
||
* 定时器
|
||
*
|
||
* <b>example:</b>
|
||
* <pre>
|
||
* <code>
|
||
* Workerman\Lib\Timer::init();
|
||
* Workerman\Lib\Timer::add($time_interval, callback, array($arg1, $arg2..));
|
||
* <code>
|
||
* </pre>
|
||
* @author walkor <walkor@workerman.net>
|
||
*/
|
||
class Timer
|
||
{
|
||
/**
|
||
* 基于ALARM信号的任务
|
||
* [
|
||
* run_time => [[$func, $args, $persistent, time_interval],[$func, $args, $persistent, time_interval],..]],
|
||
* run_time => [[$func, $args, $persistent, time_interval],[$func, $args, $persistent, time_interval],..]],
|
||
* ..
|
||
* ]
|
||
* @var array
|
||
*/
|
||
protected static $_tasks = array();
|
||
|
||
/**
|
||
* event
|
||
* @var event
|
||
*/
|
||
protected static $_event = null;
|
||
|
||
|
||
/**
|
||
* 初始化
|
||
* @return void
|
||
*/
|
||
public static function init($event = null)
|
||
{
|
||
if($event)
|
||
{
|
||
self::$_event = $event;
|
||
}
|
||
else
|
||
{
|
||
pcntl_signal(SIGALRM, array('\Workerman\Lib\Timer', 'signalHandle'), false);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 信号处理函数,只处理ALARM事件
|
||
* @return void
|
||
*/
|
||
public static function signalHandle()
|
||
{
|
||
if(!self::$_event)
|
||
{
|
||
pcntl_alarm(1);
|
||
self::tick();
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* 添加一个定时器
|
||
* @param int $time_interval
|
||
* @param callback $func
|
||
* @param mix $args
|
||
* @return void
|
||
*/
|
||
public static function add($time_interval, $func, $args = array(), $persistent = true)
|
||
{
|
||
if($time_interval <= 0)
|
||
{
|
||
echo new Exception("bad time_interval");
|
||
return false;
|
||
}
|
||
|
||
if(self::$_event)
|
||
{
|
||
return self::$_event->add($time_interval, $persistent ? EventInterface::EV_TIMER : EventInterface::EV_TIMER_ONCE , $func, $args);
|
||
}
|
||
|
||
if(!is_callable($func))
|
||
{
|
||
echo new Exception("not callable");
|
||
return false;
|
||
}
|
||
|
||
if(empty(self::$_tasks))
|
||
{
|
||
pcntl_alarm(1);
|
||
}
|
||
|
||
$time_now = time();
|
||
$run_time = $time_now + $time_interval;
|
||
if(!isset(self::$_tasks[$run_time]))
|
||
{
|
||
self::$_tasks[$run_time] = array();
|
||
}
|
||
self::$_tasks[$run_time][] = array($func, $args, $persistent, $time_interval);
|
||
return true;
|
||
}
|
||
|
||
|
||
/**
|
||
* 尝试触发定时回调
|
||
* @return void
|
||
*/
|
||
public static function tick()
|
||
{
|
||
if(empty(self::$_tasks))
|
||
{
|
||
pcntl_alarm(0);
|
||
return;
|
||
}
|
||
|
||
$time_now = time();
|
||
foreach (self::$_tasks as $run_time=>$task_data)
|
||
{
|
||
if($time_now >= $run_time)
|
||
{
|
||
foreach($task_data as $index=>$one_task)
|
||
{
|
||
$task_func = $one_task[0];
|
||
$task_args = $one_task[1];
|
||
$persistent = $one_task[2];
|
||
$time_interval = $one_task[3];
|
||
try
|
||
{
|
||
call_user_func_array($task_func, $task_args);
|
||
}
|
||
catch(\Exception $e)
|
||
{
|
||
echo $e;
|
||
}
|
||
if($persistent)
|
||
{
|
||
self::add($time_interval, $task_func, $task_args);
|
||
}
|
||
}
|
||
unset(self::$_tasks[$run_time]);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 删除定时器
|
||
* @param $timer_id
|
||
*/
|
||
public static function del($timer_id)
|
||
{
|
||
if(self::$_event)
|
||
{
|
||
return self::$_event->del($timer_id, EventInterface::EV_TIMER);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 删除所有定时
|
||
*/
|
||
public static function delAll()
|
||
{
|
||
self::$_tasks = array();
|
||
pcntl_alarm(0);
|
||
if(self::$_event)
|
||
{
|
||
self::$_event->clearAllTimer();
|
||
}
|
||
}
|
||
}
|