程序 = 状态机
进程 (状态机) 管理的 API
理解 “文件描述符”
了解状态机 API 的应用
fork()
in the road计算机系统的状态 $(M_s, R_s)$ 包含
进程还需要访问操作系统中的对象。
UNIX: Everything is a file!
/dev/random
/dev/sda
/proc/[pid]/maps
Everything is a file → “Everything 描述符”
例子:备份 stdout
freopen("a.txt", "w", stdout);
想看看进程打开了什么文件?
ls -l /proc/[pid]/fd
lsof -p pid
有惊喜
fork()
时进程的所有文件描述符会被子进程继承。
一个非常精巧的设计!
./a.out
等等……
void f(int x, int y) {
int z = x * y;
if (z == 18) {
bug();
}
}
int main() {
int x = nondet(), y = x * 2;
f(x, y);
}
执行一次程序,可以得到一条路径
int dfs(int pc) {
try_true_branch(pc); restore();
try_false_branch(pc); restore();
}
int dfs_fork(int pc) {
if ((pid = fork()) == 0) try_true_branch(pc);
else try_false_branch(pc);
}
假设你实现的 NEMU 需要启动很多份
./nemu dummy.elf
./nemu add.elf
./nemu add-longlong.elf
...int main() {
nemu_init(); // only once
while (1) {
file = get_start_request();
if ((pid = fork()) == 0) {
// bad practice: no error checking
load_file();
}
...
典型的例子
定期给程序做备份性质的快照
计算机系统里没有魔法。机器永远是对的。
fork()
in the road (HotOS'19)int fork();
int execve(char *filename, char * argv, char * envp);
Fork: 更好上手,但暗藏杀机 (printf; 线程; ...)
int posix_spawn(pid_t *pid, char *path,
posix_spawn_file_actions_t *file_actions,
posix_spawnattr_t *attrp,
char * argv[], char * envp[]);
参数
pid
: 返回的进程号path
: 程序 (重置的状态机)file_actions
: open, close, dupattrp
: 信号、进程组等信息argv
, envp
: 同 execve
fork()
in the Roadfork()
的七宗罪
create()
后 fork()
的难题提出的建议
本次课内容与目标
Takeaway messages