Open supergem3000 opened 8 months ago
15. 操作系统上的进程 (jyywiki.cn) 线程、进程和操作系统 操作系统同时保存多个状态机。 进程有自己的内存空间,看不到其他进程的内存空间。线程共享内存。
15. 操作系统上的进程 (jyywiki.cn)
操作系统同时保存多个状态机。 进程有自己的内存空间,看不到其他进程的内存空间。线程共享内存。
在 UNIX/Linux 系统内核完成初始化后,只有一个 init 进程被启动,从此以后,操作系统内核就化身为了一个事件驱动的程序、状态机的管理者,仅在中断和系统调用发生时开始执行。 那么SysCall必须有两个系统调用:创建进程(创建状态机),终止进程(终止状态机)
fork()
创建状态机应该提供什么样的 API?UNIX 的答案:fork
int fork();
做一份状态机完整的复制(内存、寄存器)。除了fork返回值不同。 fork:复制失败返回-1,新创建进程返回0,执行fork的进程返回子进程的进程号。 因为状态机是复制的,因此总能找到父子关系。 因此有了进程树(pstree)
理解fork:习题1
pid_t x = fork(); pid_t y = fork(); printf("%d %d\n", x, y);
到底创建了几个状态机?输出是什么? 答:创建了4个,输出可能性很多,比如{id1} {id2}\n {id1} 0\n 0 {id3}\n 0 0\n
{id1} {id2}\n {id1} 0\n 0 {id3}\n 0 0\n
理解fork:习题2
for (int i = 0; i < 2; i++) { fork(); printf("Hello\n"); }
./a.out
./a.out | cat
printf不总是直接打印到标准输出,比如认为输出到的是管道,会把打印的内容缓冲。fork的时候缓冲区也复制了。
printf
execve()
状态机只是复制,怎么创建出各种各样的进程呢?怎么把复制出的程序变成另外一个程序呢? UNIX 的答案:execve。将当前进程重置成一个可执行文件描述状态机的初始状态
int execve(const char *filename, char * const argv[], char * const envp[]);
execve行为:执行名为filename的程序,允许对新状态机设置参数argv和环境变量envp,对应main的参数。 execve是唯一能够“执行程序”的系统调用。因此也是strace的第一个系统调用。
_exit()
还缺少一个销毁状态机的函数。 UNIX的答案:_exit
exit是c语言标准库,为了区分开加了下划线 void _exit(int status); 销毁当前状态机,并允许有一个返回值。 子进程终止会通知父进程。 几种exit的不同: exit(0) stdlib.h中声明,c语言main运行完实际还会有一段代码(等于把写的程序做了一层包装)。调用exit,自己写的程序停止,包装代码还会运行到结束。 _exit(0) glibc中的syscall wrapper。终止整个进程,执行exit_group系统调用。进程直接停止,上面说的包装代码不会运行。 syscall(SYS_exit, 0) 执行exit系统调用终止当前线程。线程直接停止,上面说的包装代码不会运行。
exit是c语言标准库,为了区分开加了下划线
void _exit(int status);
销毁当前状态机,并允许有一个返回值。 子进程终止会通知父进程。 几种exit的不同:
exit(0)
_exit(0)
syscall(SYS_exit, 0)
在 UNIX/Linux 系统内核完成初始化后,只有一个 init 进程被启动,从此以后,操作系统内核就化身为了一个事件驱动的程序、状态机的管理者,仅在中断和系统调用发生时开始执行。 那么SysCall必须有两个系统调用:创建进程(创建状态机),终止进程(终止状态机)
复制状态机:
fork()
创建状态机应该提供什么样的 API?UNIX 的答案:fork
做一份状态机完整的复制(内存、寄存器)。除了fork返回值不同。 fork:复制失败返回-1,新创建进程返回0,执行fork的进程返回子进程的进程号。 因为状态机是复制的,因此总能找到父子关系。 因此有了进程树(pstree)
理解fork:习题1
到底创建了几个状态机?输出是什么? 答:创建了4个,输出可能性很多,比如
{id1} {id2}\n {id1} 0\n 0 {id3}\n 0 0\n
理解fork:习题2
./a.out
打印了6个Hello./a.out | cat
打印了8个Hello重置状态机:
execve()
状态机只是复制,怎么创建出各种各样的进程呢?怎么把复制出的程序变成另外一个程序呢? UNIX 的答案:execve。将当前进程重置成一个可执行文件描述状态机的初始状态
execve行为:执行名为filename的程序,允许对新状态机设置参数argv和环境变量envp,对应main的参数。 execve是唯一能够“执行程序”的系统调用。因此也是strace的第一个系统调用。
销毁状态机:
_exit()
还缺少一个销毁状态机的函数。 UNIX的答案:_exit