1. 应用程序视角的操作系统


<aside> 📖 Linux 启动流程

CPU Reset → Firmware → Loader → Kernel   → 第一个程序  → 程序 (状态机) 执行 + 系统调用

</aside>

<aside> 📖 操作系统为 (所有) 程序提供 API

2. 状态机管理


<aside> 📖 操作系统:状态机的管理者

C 程序 = 状态机

虚拟化:操作系统在物理内存中保存多个状态机

2.1 创建状态机 fork()

如果要创建状态机,我们应该提供什么样的 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>

2.2 替换状态机 execve()

光有 fork 还不够,怎么 “执行别的程序”?

<aside> 📖 UNIX 的答案 execve

将当前运行的状态机重置成成另一个程序的初始状态

int execve(const char *filename, char * const argv, char * const envp);

<aside> 📖 环境变量 Environment Variable

“应用程序执行的环境”

使用 env 命令查看:

2.1 终止状态机 _exit()

有了 fork, execve 我们就能自由执行任何程序了,最后只缺一个销毁状态机的函数!

<aside> 📖 UNIX 的答案 _exit

立即摧毁状态机

void _exit(int status)

<aside> 📖 三种方法