Appearance
第 08 课 · 从源码到进程
代码怎么变成「上班中的部门」。
作者:曹宇春
先记住这个类比
写代码 ≈ 写操作手册草稿。
编译链接 ≈ 翻译装订成册。
启动程序 ≈ 把成册手册发到部门桌上,部门开始干活 = 进程。
正式概念(人话版)
四步流水线(C/Go 等编译型语言思路)
源码
→ 编译成目标文件(各章节译稿)
→ 链接成可执行文件(装订,解决交叉引用)
→ OS 加载并 exec(部门按手册上班)动态库(.dylib / .so)≈ 手册写「公共工具去公共书架取」——多 App 共享一份,省桌面。
Unix 经典:fork + exec
- fork:复印一个和我一样的部门(子进程)
- exec:把复印件换成另一个程序的手册
你在 Terminal 敲命令:壳进程 fork → 子进程 exec → 变成 node / git / agent。
macOS 上的 .app
.app 看起来是一个图标,其实是 文件夹:真正可执行文件常在 Contents/MacOS/。
Electron 应用再嵌一套 Chromium + Node —— 所以体积大、启动后进程多(回到第 02 课)。
系统调用再现
程序读文件、建网络、开进程,都要 syscall 找总管。
用户态 = 普通员工;内核态 = 总管办公室。频繁上下楼会有开销。
在你电脑上看一眼
bash
# 看某个 App 包结构(示例)
ls "/Applications/Safari.app/Contents/MacOS" 2>/dev/null
# 当前壳与进程信息
echo $$
ps -p $$ -o pid,ppid,command$$ 是当前 shell 的 PID;ppid 是父进程(谁招了这个部门)。
开发里什么时候用得上
npm run xxx/npx:壳 → 子进程链,端口与环境变量都在这条链上- 路径、权限、架构(arm64 vs x86)不对:常在「装订/加载」阶段失败,不是业务逻辑
- 调试「子进程秒退」:看父进程是否收到错误码、是否缺动态库
练习
- 在 Terminal 运行
echo $$,再用ps查出它的父进程是谁。 - 打开一个
.app的Contents,找真正的可执行文件名。
小结
- 编译链接 = 写手册;exec = 部门按手册上班
- fork/exec 是 Unix 开程序的标准姿势
- Electron / 大 IDE 重,是因为嵌了整套浏览器引擎
下一课:门禁与钥匙——安全与权限。