libuv basics
libuv 的基本原理是维护一个持续运行的事件循环,当收到 I/O 通知的时候,运行与该 I/O 有关的回调函数。对于网络 I/O 由于有跨平台的的 aio 接口,所以可以直接在事件循环内调度。对于文件 I/O, 没有跨平台的 I/O 接口,所以替代方案是起一个线程池,将 I/O 操作提到另外的线程去执行,保证 I/O 操作不会影响当前线程(这需要额外分配 cpu 资源用于线程切换)。
事件循环的限制是:
- 回调函数如果包含 Blocking I/O 那么整个事件循环都会被堵塞
- CPU 密集运算不适合放在事件循环进程里运行,否则也会影响事件调度。
libuv 中的几个重要概念:
- request: 代表一个只会执行一个回调的任务 …
源码阅读 - picol - 一个 500line 的 TCL Script 解释器
这是 Redis 的作者 antirez 在无聊的时候写的一个健脑锻炼 - 写了一个大约 500 行左右的解释器,可以运行 TCL 脚本代码。代码看起来很优雅,没有用什么奇奇怪怪的技术,实打实地用好了字符串解析,内存分配这些技巧。
main
: 根据参数进入 REPL 模式或者执行脚本picolInitInterp
: 初始化解释器,解释器的数据结构是栈帧的链表和TCL语言内部函数的链表。picolRegisterCoreCommands
: 将用 C 实现的函数注册为 TCL 语言的内部函数 - 体现了 SICP 中介绍的语言抽象picolEval
: 解释执行 TCL 字符串形式的代码。picolGetToken
: 将 TCL 字符串形式的代码变为有语法意义的 Token。
从实现上看,Picol 简化了解释器实现,省略掉了 OPCODE 的编译,直接将 token 用于解释执行 …
read moreProtothreads - lightweight stackless threads
本文介绍了 Protothread 这种无栈线程的小众实现,由于不需要线程或者多进程就能实现多任务协程,它被用于 Arduino / 感应器这种嵌入式设备中。每个 PT 仅占用两个 bytes 大小,理论上你可以创建比 Actor 模型还多两个数量级的并发任务出来。由于仅仅是几个 C 的宏,它极具迁移性,甚至可以在无 OS 的环境运行。它的核心实现就下面几行代码:
struct pt { unsigned short lc; };
#define PT_THREAD(name_args) char name_args
#define PT_BEGIN(pt) switch(pt->lc) { case 0:
#define PT_WAIT_UNTIL(pt, c) pt->lc = __LINE__; case …
theBeamBook - The Erlang Runtime System
本文是一本尚未完工的书,讲了 Erlang 底层是如何实现它的调度和解释器的。
- Erlang 的最底层是 ERTS, 它掌管进程调度(Erlang 自己重写了整个专属于自己运行时的进程,有别于系统进程)
- BEAM 是 Erlang 的虚拟机,用来执行指令。
- Process 的本质是大约几百个 bytes 的数据结构,包含了进程控制的一些字段(PCB) 外加 Stack, Heap, Mailbox.
- Mailbox 的本质是一个无锁消息队列。
- Scheduling 的策略是抢占式调度,任一时刻 CPU 只执行一个进程,时间片花完了就推后去执行别的进程。它的内部维护了两个队列,一个专门维护被 receive message 堵塞的进程,另外一个维护可执行的进程。
如何使用 Wireshark
Julia Evans 的新文章,讲怎么做网络数据包的诊断分析。
- 这个工具可以图形化查看网络数据包。如果生产环境上诊断不方便,用 tcpdump 下来到 local 来查。
原文是在 debian-based distros 上使用 sudo apt install wireshark
。我尝试了下,在 macOS 上可以用 brew install wireshark 得到命令行工具,使用 brew cask install wireshar
获得图形界面工具。
打开 tcpdump 的数据包中, 可以看到 ACK, SYN 等 TCP 包具体发来发去的那些 packet。
举个例子,connection reset 是个常见的问题。我们可以查这个序列,如果 …
read more程序员日常使用的 Bash Tricks
本文介绍了 Bash 使用的不少小窍门。
- 设定
export CDPATH=~/works:~/code:~/playground
, 不论在哪里都能快速用cd dir
这样的语法跳到那个目录去。 - 使用
!!
运行上一条命令。
$ py.test tests
$ !!
- 使用
!*
扩展前一条命令的参数到本命令
$ touch filea fileb filec
$ chmod 777 !*
- ctrl+r 从历史里面去找
shopt -s cdspell
可以自动纠正错误的 cd 路径- 使用
cd -
在两个路径之间来回切换 - 用 bind -p 查看 bash 内置的快捷键
衍生思考:很不错的总结,我再补几个我常用的:
- 上条命令有 typo …