OSTEP第5章 插叙:进程API
文章目录
- unix系统创建新进程的方式是一对系统调用
fork()
和exec()
,系统调用wait()
用于等待创建的子进程执行完
fork()系统调用
- 例子:使用fork
|
|
- 运行输出:
|
|
- 进程调用fork创建新进程,新进程几乎与原进程完全一样,对OS来说有两个完全一样的程序在运行,并都从fork返回
- fork创建的子进程不会从main开始执行,而是直接从fork中返回,就好像是它自己调用了fork
- 子进程并非完全拷贝父进程。它虽然拥有自己的地址空间、寄存器等,但从fork返回的值与父进程不一样:父进程从fork返回的值是新创建子进程的PID,子进程从fork中返回0,这使得子进程和父进程接下来可以做不同的事
- fork时子进程和父进程谁先执行,由cpu调度程序决定
wait()系统调用
- 例子:使用wait
|
|
- 运行输出:
|
|
- 在fork结束后,父进程调用wait可等待子进程状态发生改变(如terminated、stopped、resumed),父进程才从wait中返回,继续执行
最后是exec()系统调用
- 例子:使用exec
|
|
- 运行输出:
|
|
- exec系统调用可让子进程执行与父进程不同的程序
- 对exec给定可执行程序的名称和运行参数,exec从可执行程序中加载代码和静态数据,用其覆盖自己的代码段和静态数据段,堆栈和其他内存空间被重新初始化,OS按照运行时参数执行该程序。
- exec并未创建新进程,而是将当前运行的程序替换为不同的程序。子进程执行exec后就像原来的进程从未运行过一样
- 对exec的成功调用永远不会返回
为什么这样设计API
- 将fork和exec分离的做法在构建shell时非常有用,这可使得shell在fork之后exec之前运行代码,这些代码可在exec运行新程序之前改变环境
shell
是一个用户程序,它首先输出提示符,用户输入命令后,shell在文件系统中找到该可执行程序,调用fork创建子进程,调用exec执行该程序,调用wait等待该命令完成。子进程结束后shell从wait返回并输出提示符等待下一个命令- fork和exec分离实现重定向:shell用fork完成子进程创建后,调用exec之前关闭标准输出,打开重定向目标文件,再用exec运行程序。
- 例子:使用fork和exec重定向输出
|
|
- 运行输出:
|
|
- 重定向的工作原理,是基于对OS管理文件描述符方式的假设。unix系统从0开始寻找可使用的文件描述符。上例中STDOUT_FILENO是第一个可用的文件描述符,将其close并open另一个文件时,使用新的文件描述符,故对标准输出文件的写入都会被写到新的文件描述符
- unix的管道也和重定向的实现类似,但用的是
pipe
系统调用。此时一个进程的输出被连接到内核管道(队列)上,另一个进程的输入也被连接到该管道。前一个进程的输出作为后一个进程的输入,可用这种方式串联多个命令共同完成任务
其他API
- kill系统调用可向进程发送信号,包括睡眠、终止等指令。整个信号子系统提供了很多向进程传递外部事件的途径
- 工具ps可查看当前运行的进程
- 工具top可查看系统中进程消耗cpu等资源的情况
作业(编码)
- 调用fork前让主进程定义变量,子进程和父进程都改变它的值时发生什么?
- 答:如下,各自维护一个副本,互不影响
|
|
- 使用open打开文件,然后fork创建子进程,子进程和父进程是否都可访问open返回的文件描述符?他们并发写入时会发生什么?
- 答:可以写,按照子进程和父进程调度的顺序串行写入
|
|
- 了解exec的变体:execl()、execle()、execlp()、execv()、execvp()和 execvP()
- 答:
- 名字带
l
的,参数以可变参数列表给出 - 名字带
v
的,参数以argv数组给出 - 名字带
p
的,指定程序时不需给完整路径,而是在PATH中查找 - 名字带
e
的,可在调用时传入指定的环境变量
- 名字带
- 函数原型:
|
|
- 父进程中使用wait返回什么?子进程中使用wait发生什么?
- 答:
- 父进程中的wait:子进程执行成功返回PID,失败返回-1
- 子进程中的wait:返回-1,不影响父进程
- 什么时候需要用waitpid?
- 答:waitpid可通过PID指定等待哪一个子进程,且可增加option参数
- 子进程中关闭标准输出后调用printf打印到标准输出会怎样?
- 答:不会打印到标准输出。若在close标准输出后open一个文件,printf将打印到该文件
|
|
- 创建两个子进程,使用pipe系统调用将一个子进程的标准输出连接到另一个子进程的标准输入
- 答:
|
|
小结
略