workman源代码阅读 - 使用信号处理器实现定时器
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了workman源代码阅读 - 使用信号处理器实现定时器相关的知识,希望对你有一定的参考价值。
<?php /** * SIGALRM信号处理器注册成功后,在什么情况下进程会收到该信号呢? * * 在Linux系统下,每个进程都有惟一的一个定时器,该定时器提供了以秒为单位的定时功能。在定时器设置的超时时间到达后,调用alarm的进程将收到SIGALRM信号。 */ /** * 启动信号处理器 */ \MySignalClazz::init(); /** * 信号处理器 * @author Administrator * */ class MySignalClazz { /** * Tasks that based on ALARM signal. * [ * 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(); /** * 注册信号处理器 */ public static function init() { pcntl_signal(SIGALRM, array(‘\MySignalClazz‘, ‘signalHandle‘), false); } /** * 信号处理器 * ALARM signal handler. * @return void */ public static function signalHandle(){ pcntl_alarm(1); // 创建一个计时器,在1秒后向进程发送一个SIGALRM信号 self::tick(); } /** * Add a timer. * * @param int $time_interval * @param callback $func * @param mixed $args * @param bool $persistent * @return bool */ public static function add($time_interval, $func, $args = array(), $persistent = true) { if ($time_interval <= 0) { echo new Exception("bad time_interval"); return false; } if (!is_callable($func)) { echo new Exception("not callable"); return false; } if (empty(self::$_tasks)) { pcntl_alarm(1); // 重新启动定时器,实现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, (array)$args, $persistent, $time_interval); return true; } /** * 单次执行函数 */ 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]); // 执行完就删除掉 } } } }
以上是关于workman源代码阅读 - 使用信号处理器实现定时器的主要内容,如果未能解决你的问题,请参考以下文章
websocket 后台新订单通知 —— Laravel 5.8 workman PHPSocket.IO教程