术语与不变量速查
高频概念、线程边界和不能破坏的约束
术语与不变量速查
高频术语
| 术语 | 含义 |
|---|---|
| Surface | 一个 terminal surface;不等于窗口,可以被 tab/split/embedded host 承载 |
| apprt | Application runtime,核心与窗口系统之间的契约 |
| Termio | terminal IO 聚合层,连接 backend、PTY、stream 和 Terminal |
| Page | 一段有自己的行列/内存布局的终端页 |
| PageList | 从 scrollback 到 active page 的链表及 storage 管理器 |
| alternate screen | 全屏程序使用的另一套 screen,通常不保留普通 scrollback |
| SharedGrid | 跨 surface 共享字体 metrics、glyph/atlas 资源的缓存单元 |
| mailbox | 跨线程传消息的队列,消息包含 ownership/lifecycle 语义 |
| dirty flag | 告诉 renderer 哪些逻辑/视觉部分需要失效或重建 |
| libghostty-vt | 不依赖完整 GUI 的终端状态/协议库 |
| embedded runtime | 由宿主提供窗口、clipboard、wakeup 等 callback 的运行模式 |
线程不变量
- IO thread 主要消费 PTY 输入、执行 parser/terminal 更新,并处理写入/控制消息。
- renderer thread 观察共享 render state、构造 cell buffers、提交 GPU frame。
- app/runtime thread 处理平台 UI、窗口、菜单、clipboard 和 app mailbox。
- search thread 的结果可能指向已经失效的 PageList node,使用前必须验证。
- thread state 只有在线程 join 后才能 deinit;mailbox/handle 不可提前释放。
所有权不变量
- C API 返回的字符串按
ghostty_string_s的 sentinel/length 规则释放; DerivedConfig的 arena 持有复制出来的字符串,不能让指针跨 config 生命周期逃逸;- resident Page 的 borrowed pointer 只在 PageList 访问约束内有效;
- surface 关闭后,runtime callback 和 Swift wrapper 都不能继续使用旧 pointer;
App.font_grid_set的共享资源要在所有 surface 退出后才释放。
解释 Ghostty 性能的五个关键词
分线程:读取、绘制、平台事件不互相阻塞。
少分配:Parser 参数、cell、atlas 和 queue 都尽量使用固定边界或缓存。
延迟失效:dirty flag、wakeup、draw timer 让更新按需发生。
共享昂贵资源:字体 grid 和 atlas 可以跨 surface 复用。
编译时裁剪:runtime、target、artifact 和 feature 在 build time 分支化。
一句话总结
Ghostty 的核心不是某个 parser 技巧,而是一组围绕“高速字节输入 → 稳定终端状态 → 可增量 GPU 绘制”的边界纪律:协议层不懂窗口,窗口层不重写终端语义,线程之间不共享不稳定对象,库接口不泄漏内部 ownership。