[Day 30] 模仿 Node 的非同步实验兼完赛心得

实作

所谓读了原始码却不实作与验证, 那不过就是对原始码的意淫而已, 所以在这个系列文的结尾总是还要写点东西的。

但因为还有太多部分没聊到, 所以我临时把最後要完成的实作改成模仿我们前面读到的 Node 原理做出来的小程序, 希望可以验证一下我们前面学到的东西。

实作目的

利用最简单的方法, 依照 Node 原理编写一个程序具有可以处理非同步方法的环境, 并且具备几个非同步方法供人调用。

概念与设计

打算在程序创建之初建立一个环境, 而这个环境支援数个非同步方法, 建完环境後就可以执行任意程序码。

以下说明想要支援的非同步方法

  1. console_timer 特定延迟秒数後 console log
  2. console_file 读取 local file 的文字, console log 出来
  3. console_encryption 加密替定文字後 console log 出来
  4. console_decryption 解密特定文字後 console log 出来

而环境的构成分成仅有一条 thread 的 event loop 和 有任意条 threads 的 thread pool

以下叙述 event loop 细节

  • 分成 4 个阶段不断循环, 藉此处理接踵而来的事件
  • 提供介面接收 main thread 和 thread pool 传过来的事件, 以下说明介面
    1. main thread 运行 console_timer这类定时方法时, 调用介面把定时事件放入 event loop 中属於 timer_stage 的最小树。
    2. main thread 运行console_file 这类系统 IO 方法时调用 OS API 且注册 IOCP 事件, 如此当 IO 结束 event loop 的 polling_stage 就可以收到该 IO 事件的结果了。
    3. console_encryption , console_decryption 这类密集 CPU 型方法被 thread pool 完成时透过 IOCP 方法送出结果, event loop 的 polling_stage 就可以收到该 IO 事件的结果了。
  • 以下叙述 4 个阶段的细节
    1. timer_stage : 维护一个最小树, 每当来到这个阶段, 就检查有没有逾时的事件, 有就执行。
    2. pending_stage : 维护一个 pending_list , 每次来到此阶段就执行整个 pending list 中的任务。最後把完成的任务放入 endgame list
    3. polling_stage : 利用 IOCP 方法接收 IO 结束的各种 AIO 事件, 再把事件放入 pending list
    4. endgame_stage : 维护一个 endgame_list , 每次来到此阶段就释放整个 endgame list 中任务的资源。

以下叙述 thread pool 细节

  • 透过 lock-free stack 来传入任务, IOCP 来传出结果, 两个方法都是 multi-thread 的演算法, 所以支援无限大的 thread pool, 当然无限增大 TP 没啥意义。
  • main thread 把 console_encryption , console_decryption 这类密集 CPU 型方法产生的事件加入 lock-free stack 只要 TP 中的 thread 闲置, 就会去 stack 取出一个任务来处理。
  • TP 中的 thread 完成事件中的任务後会利用 IOCP 的方法把事件传给 event loop 中的 polling_stage。

程序码

最後贴上程序码, 其中有大量注解, 希望帮助大家看懂。

https://gist.github.com/leon123858/5b270a3c57f8744c4e4a334eb57f282e

声明

这个系列文写到这边算是画下一个句点了, 其中内容大多是我阅读原始码以及官方文件所得来, 这些东西真的是有点硬, 而且我这次又是挑选了 IOCP 路线来说(文件基本上都是 epoll 的版本), 导致我很多地方都只能半猜不猜得过去, 要是我有讲错说错可以跟我反映, 我会做修订。

後话与心得

不得不说, 30 天真的很短, 很多想写的都还没写到就已经结束了。还有蛮多想聊的都还没说到, 包含 node 中 await 的原理, threadpool 的 scheduling , .......... 等等。不过我想这篇不是完结, 我未来应该会把我在第一天中, 设定想写的目标写完, 那就暂时先跟大家说 bye bye 啦


<<:  {DAY 18} Pandas 学习笔记part.4

>>:  Alpine Linux Porting (一点九?)

Day14 - 机智接案生活

看过很多文章提到程序设计师接案的陷阱,因自己非本科出身,所以觉得这些陷阱都不会发生在自己身上,再加上...

蓝牙小知识

名称的由来 Bluetooth是斯堪地那维亚语言的Blåtand/Blåtann 借10世纪丹麦和...

[Day8] Android - Kotlin笔记:JetPack - Core KTX

Core KTX 包含的module有: androidx.core.animation andro...

【Day 11】Variables 变数

接下来我们要针对基本变数型态做一些简单的介绍,以及超级重要的阵列!那这篇先以variables为主。...

[Day29] 资安自学之路 小回顾

程序,资安是我生命中的意外 国高中从没想过这些 我从小六的目标就是当外科医生 因为我深受怪医黑杰克,...