Timer.php 4.3 KB

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