当前位置: 首页 > news >正文

编写网站代码用手机制作表格的软件

编写网站代码,用手机制作表格的软件,苏州首页关键词优化,西安建站网站原文首发链接#xff1a;Swoole 源码分析之 Timer 定时器模块 大家好#xff0c;我是码农先森。 引言 Swoole 中的毫秒精度的定时器。底层基于 epoll_wait 和 setitimer 实现#xff0c;数据结构使用最小堆#xff0c;可支持添加大量定时器。 在同步 IO 进程中使用 seti…原文首发链接Swoole 源码分析之 Timer 定时器模块 大家好我是码农先森。 引言 Swoole 中的毫秒精度的定时器。底层基于 epoll_wait 和 setitimer 实现数据结构使用最小堆可支持添加大量定时器。 在同步 IO 进程中使用 setitimer 和信号实现如 Manager 和 TaskWorker 进程在异步 IO 进程中使用 epoll_wait/kevent/poll/select 超时时间实现。 定时器的添加和删除全部为内存操作。在官方的基准测试脚本中添加或删除 10 万个随机时间的定时器耗时为 0.08s 左右因此性能是非常高效的。 源码拆解 我们在分析源代码之前先看这段使用定时器的代码。Timer::after 函数是设置一个一次性的定时器也就是执行一次就结束了常用于执行一次性任务的场景。Timer::tick 函数会每间隔一段时间执行一次类似一个闹钟的机制常用于需要定时执行任务的场景。 ?php // 设置一个一次性定时器 Swoole\Timer::after(1000, function(){echo timer after timeout\n; });// 设置一个间隔时钟定时器 Swoole\Timer::tick(1000, function(){echo timer tick timeout\n; });按照之前分析源代码的策略先对整个源码的调用流程进行梳理以便于让我们有个整体的印象调用流程如下图所示。 swoole_timer.cc 这个源码文件中定义了两个函数 swoole_timer_after、swoole_timer_tick。从这段代码中可以看出唯一的区别是在调用 timer_add 函数时的传参有所不同一个是 false一个是 true表示的是是否需要持久化的执行任务。另外 timer_add 函数实现了一些根据细化的逻辑例如参数的解析、一些检查判断的工作。最后根据 persistent 参数判断是否执行持久化的操作。 // 定义 PHP 函数 swoole_timer_after // swoole-src/ext-src/swoole_timer.cc:221 static PHP_FUNCTION(swoole_timer_after) {timer_add(INTERNAL_FUNCTION_PARAM_PASSTHRU, false); }// 定义 PHP 函数 swoole_timer_tick // swoole-src/ext-src/swoole_timer.cc:225 static PHP_FUNCTION(swoole_timer_tick) {timer_add(INTERNAL_FUNCTION_PARAM_PASSTHRU, true); }// 添加定时任务到定时器中, 并根据持久性标志判断是否需要一直执行 // swoole-src/ext-src/swoole_timer.cc:155 static void timer_add(INTERNAL_FUNCTION_PARAMETERS, bool persistent) {zend_long ms;Function *fci (Function *) ecalloc(1, sizeof(Function));TimerNode *tnode;// 解析参数ZEND_PARSE_PARAMETERS_START(2, -1)Z_PARAM_LONG(ms)Z_PARAM_FUNC(fci-fci, fci-fci_cache)Z_PARAM_VARIADIC(*, fci-fci.params, fci-fci.param_count)ZEND_PARSE_PARAMETERS_END_EX(goto _failed);// 检查定时器值 ms 是否小于预定义的最小值 SW_TIMER_MIN_MSif (UNEXPECTED(ms SW_TIMER_MIN_MS)) {php_swoole_fatal_error(E_WARNING, Timer must be greater than or equal to ZEND_TOSTR(SW_TIMER_MIN_MS));_failed:efree(fci);RETURN_FALSE;}// 进行额外的检查// no server || user worker || task process with async modeif (!sw_server() || sw_server()-is_user_worker() ||(sw_server()-is_task_worker() sw_server()-task_enable_coroutine)) {php_swoole_check_reactor();}// 使用指定的毫秒数、持久性标志、回调函数 timer_callback 和函数指针 fci 添加一个定时器tnode swoole_timer_add((long) ms, persistent, timer_callback, fci);if (UNEXPECTED(!tnode)) {php_swoole_fatal_error(E_WARNING, add timer failed);goto _failed;}// 为定时器节点 tnode 设置类型和析构函数tnode-type TimerNode::TYPE_PHP;tnode-destructor timer_dtor;// 根据持久性标志会一直执行定时的任务if (persistent) {if (fci-fci.param_count 0) {uint32_t i;zval *params (zval *) ecalloc(fci-fci.param_count 1, sizeof(zval));for (i 0; i fci-fci.param_count; i) {ZVAL_COPY(params[i 1], fci-fci.params[i]);}fci-fci.params params;} else {fci-fci.params (zval *) emalloc(sizeof(zval));}fci-fci.param_count 1;ZVAL_LONG(fci-fci.params, tnode-id);} else {// 只会执行一次sw_zend_fci_params_persist(fci-fci);}sw_zend_fci_cache_persist(fci-fci_cache);RETURN_LONG(tnode-id); }在 timer.cc 源码文件中 swoole_timer_add 这个函数会检查是否已经有可用的定时器管理对象如果没有的话会进行实例化创建一个然后通过 SwooleTG.timer-add() 方法添加一个定时器任务。 // 这段代码用于添加一个定时器到 Swoole 框架中的定时器管理器中 // swoole-src/src/wrapper/timer.cc:40 TimerNode *swoole_timer_add(long ms, bool persistent, const TimerCallback callback, void *private_data) {// 这里检查定时器是否可用if (sw_unlikely(!swoole_timer_is_available())) {// 如果定时器不可用则会创建一个新的对象SwooleTG.timer new Timer();// 并对其进行初始化if (sw_unlikely(!SwooleTG.timer-init())) {// 若初始化失败就会释放内存delete SwooleTG.timer;SwooleTG.timer nullptr;return nullptr;}}// 调用定时器对象的 add 方法向定时器中添加一个定时器return SwooleTG.timer-add(ms, persistent, private_data, callback); }这个函数 *Timer::add 会构建一个新的定时器节点并且设置一些属性值例如类型、执行时间、回调函数等。最后会将定时器节点加入到最小堆的数据结构中。 // 用于向定时器管理器中添加一个新的定时器节点 // swoole-src/src/core/timer.cc:106 TimerNode *Timer::add(long _msec, bool persistent, void *data, const TimerCallback callback) {// 检查传入的毫秒数 _msec 是否小于等于 0if (sw_unlikely(_msec 0)) {swoole_error_log(SW_LOG_WARNING, SW_ERROR_INVALID_PARAMS, msec value[%ld] is invalid, _msec);return nullptr;}// 获取当前相对毫秒数并检查其是否小于 0int64_t now_msec get_relative_msec();if (sw_unlikely(now_msec 0)) {return nullptr;}// 创建一个新的定时器节点 tnode// 并设置节点的数据、类型、执行时间、间隔、状态、回调函数、轮数以及析构函数TimerNode *tnode new TimerNode();tnode-data data;tnode-type TimerNode::TYPE_KERNEL;tnode-exec_msec now_msec _msec;tnode-interval persistent ? _msec : 0;tnode-removed false;tnode-callback callback;tnode-round round;tnode-destructor nullptr;// 更新下一个计划触发时间// 如果当前没有下一个计划或者新的时间比当前下一个计划更早// 则更新为新的时间。if (next_msec_ 0 || next_msec_ _msec) {set(this, _msec);next_msec_ _msec;}// 给定时器节点分配一个唯一的IDtnode-id _next_id;if (sw_unlikely(tnode-id 0)) {tnode-id 1;_next_id 2;}// 将节点加入堆中同时更新堆的索引tnode-heap_node heap.push(tnode-exec_msec, tnode);if (sw_unlikely(tnode-heap_node nullptr)) {delete tnode;return nullptr;}// 记录节点信息map.emplace(std::make_pair(tnode-id, tnode));swoole_trace_log(SW_TRACE_TIMER,id%ld, exec_msec% PRId64 , msec%ld, round% PRIu64 , exist%lu,tnode-id,tnode-exec_msec,_msec,tnode-round,count());// 返回新添加的定时器节点return tnode; }总结 Swoole 中实现了毫秒精度的定时器而原生的 PHP 中只支持到秒级别。数据结构使用最小堆支持添加大量定时器全部为内存操作且十分高效。定时器在实际的业务场景中应用也是非常广泛常用于延时或定时执行的任务中例如订单超时未付款自动取消等场景。
http://www.zqtcl.cn/news/22766/

相关文章:

  • 建筑装饰和网站建设哪个好泉州企业做网站
  • 驻马店河南网站建设国内免费开源crm系统大全
  • 运城有做网站设计中国建筑招聘
  • 巴彦淖尔市做网站公司重庆百度搜索排名优化
  • 做网站有必要用wordpress天河建设网站企业
  • 做汽车团购的网站有哪些怎么做个手机版的网站吗
  • 做淘宝客网站需要什么要求吗做网站选择虚拟主机好是服务器
  • 网站建设相关语言响应式相册网站
  • 陕西省住房和城乡建设厅综合网站东莞网站建设制作公司排名
  • 中等职业学校示范建设专题网站点餐网站模板 手机端
  • 徐州手机网站建设制作小红书 wordpress
  • 网站开发需要懂多少代码网站建设平台怎么做
  • 网站域名做301成都私人视频网站制作平台
  • 保定软件开发网站制作关键词工具软件
  • wordpress加cdn山东自助seo建站
  • 深圳有实力的网站建设服务商外贸公司网站模板免费
  • 选服务好的佛山网站建设百度登录首页
  • 烟台北京网站建设劳保手套网站建设
  • 中小企业网站建设多少钱烟台网站制作哪家好
  • 网站很久没被收录的新闻怎么处理厦门网站建设一般多少钱
  • 商务定制网站在wordpress上添加
  • html做游戏网站网站建设公司营销话术
  • 没有数据怎么做网站wordpress获取用户文章
  • 网络网站建设办公国家重大建设项目库网站注册
  • 网站在正在建设中邢台市建设局安全监督管理网站
  • 网站内容建设运维服务器seo网站推广方式
  • 西部建设网站合肥城乡建设网站首页
  • 做请柬网站成都旅游景点攻略
  • 广州做企业网站jsp网站开发步骤
  • zencart 网站建设绍兴seo计费