<aside> 📖 Linux 启动流程
CPU Reset → Firmware → Loader → Kernel → 第一个程序 → 程序 (状态机) 执行 + 系统调用
</aside>
<aside> 📖 操作系统为 (所有) 程序提供 API
<aside> 📖 操作系统:状态机的管理者
C 程序 = 状态机
虚拟化:操作系统在物理内存中保存多个状态机
如果要创建状态机,我们应该提供什么样的 API?
<aside> 📖 UNIX的答案 fork
int fork()
做一份状态机完整的复制 (内存、寄存器现场)
因为状态机是复制的,因此总能找到 “父子关系”
<aside> 📖 Fork Bomb
:(){:|:&};: # 一行版本
:() { # 格式化一下
: | : &
}; :
fork() { # bash: 允许冒号作为标识符……
fork | fork &
}; fork
</aside>
<aside> 📖 实践
for (int i = 0; i < 2; i++) {
fork();
printf("Hello\\n");
}
printf输出时会先输出到缓冲区,有的一行flush一次,有的达到一定大小flush一次
使用 int fflush( FILE *stream );
</aside>
光有 fork 还不够,怎么 “执行别的程序”?
<aside> 📖 UNIX 的答案 execve
将当前运行的状态机重置成成另一个程序的初始状态
int execve(const char *filename, char * const argv, char * const envp);
<aside> 📖 环境变量 Environment Variable
“应用程序执行的环境”
使用 env 命令查看:
有了 fork, execve 我们就能自由执行任何程序了,最后只缺一个销毁状态机的函数!
<aside> 📖 UNIX 的答案 _exit
立即摧毁状态机
void _exit(int status)
<aside> 📖 三种方法
exit(0)
- stdlib.h 中声明的 libc 函数
_exit(0)
- glibc 的 syscall wrapper
syscall(SYS_exit, 0)