Timer.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. <?php
  2. namespace Workerman\Lib;
  3. use \Workerman\Events\EventInterface;
  4. use \Exception;
  5. /**
  6. *
  7. * 定时器
  8. *
  9. * <b>example:</b>
  10. * <pre>
  11. * <code>
  12. * Workerman\Lib\Timer::init();
  13. * Workerman\Lib\Timer::add($time_interval, callback, array($arg1, $arg2..));
  14. * <code>
  15. * </pre>
  16. * @author walkor <walkor@workerman.net>
  17. */
  18. class Timer
  19. {
  20. /**
  21. * 基于ALARM信号的任务
  22. * [
  23. * run_time => [[$func, $args, $persistent, time_interval],[$func, $args, $persistent, time_interval],..]],
  24. * run_time => [[$func, $args, $persistent, time_interval],[$func, $args, $persistent, time_interval],..]],
  25. * ..
  26. * ]
  27. * @var array
  28. */
  29. protected static $_tasks = array();
  30. /**
  31. * event
  32. * @var event
  33. */
  34. protected static $_event = null;
  35. /**
  36. * 初始化
  37. * @return void
  38. */
  39. public static function init($event = null)
  40. {
  41. if($event)
  42. {
  43. self::$_event = $event;
  44. }
  45. else
  46. {
  47. pcntl_signal(SIGALRM, array('\Workerman\Lib\Timer', 'signalHandle'), false);
  48. }
  49. }
  50. /**
  51. * 信号处理函数,只处理ALARM事件
  52. * @return void
  53. */
  54. public static function signalHandle()
  55. {
  56. if(!self::$_event)
  57. {
  58. pcntl_alarm(1);
  59. self::tick();
  60. }
  61. }
  62. /**
  63. * 添加一个定时器
  64. * @param int $time_interval
  65. * @param callback $func
  66. * @param mix $args
  67. * @return void
  68. */
  69. public static function add($time_interval, $func, $args = array(), $persistent = true)
  70. {
  71. if($time_interval <= 0)
  72. {
  73. echo new Exception("bad time_interval");
  74. return false;
  75. }
  76. if(self::$_event)
  77. {
  78. return self::$_event->add($time_interval, $persistent ? EventInterface::EV_TIMER : EventInterface::EV_TIMER_ONCE , $func, $args);
  79. }
  80. if(!is_callable($func))
  81. {
  82. echo new Exception("not callable");
  83. return false;
  84. }
  85. if(empty(self::$_tasks))
  86. {
  87. pcntl_alarm(1);
  88. }
  89. $time_now = time();
  90. $run_time = $time_now + $time_interval;
  91. if(!isset(self::$_tasks[$run_time]))
  92. {
  93. self::$_tasks[$run_time] = array();
  94. }
  95. self::$_tasks[$run_time][] = array($func, $args, $persistent, $time_interval);
  96. return true;
  97. }
  98. /**
  99. * 尝试触发定时回调
  100. * @return void
  101. */
  102. public static function tick()
  103. {
  104. if(empty(self::$_tasks))
  105. {
  106. pcntl_alarm(0);
  107. return;
  108. }
  109. $time_now = time();
  110. foreach (self::$_tasks as $run_time=>$task_data)
  111. {
  112. if($time_now >= $run_time)
  113. {
  114. foreach($task_data as $index=>$one_task)
  115. {
  116. $task_func = $one_task[0];
  117. $task_args = $one_task[1];
  118. $persistent = $one_task[2];
  119. $time_interval = $one_task[3];
  120. try
  121. {
  122. call_user_func_array($task_func, $task_args);
  123. }
  124. catch(\Exception $e)
  125. {
  126. echo $e;
  127. }
  128. if($persistent)
  129. {
  130. self::add($time_interval, $task_func, $task_args);
  131. }
  132. }
  133. unset(self::$_tasks[$run_time]);
  134. }
  135. }
  136. }
  137. /**
  138. * 删除定时器
  139. * @param $timer_id
  140. */
  141. public static function del($timer_id)
  142. {
  143. if(self::$_event)
  144. {
  145. return self::$_event->del($timer_id, EventInterface::EV_TIMER);
  146. }
  147. }
  148. /**
  149. * 删除所有定时
  150. */
  151. public static function delAll()
  152. {
  153. self::$_tasks = array();
  154. pcntl_alarm(0);
  155. if(self::$_event)
  156. {
  157. self::$_event->clearAllTimer();
  158. }
  159. }
  160. }