API:
应用程序编程接口(英语:Application Programming Interface,简称:API),是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。——百度百科
fork():
创建新进程,新进程为子进程,原来进程为父进程。二者相互独立。
子进程会拷贝父进程的代码段,栈,堆等内容。
(PID:进程描述符)
当fork()成功调用后,子进程的rc=0,父进程的rc>0。
运行结果:
结果分析:
1.子进程不会从main函数开始执行,所以“hello world”只执行了一次,并且pid为父进程的。
2.父进程的返回值是子进程的PID,子进程返回值为0。
思考:
这段代码会产生几个进程?
8个,父进程和子进程都会进入“rc=fork()”语句。
wait():
字面意思,父进程等待子进程运行结束后才返回。
exec():
让子进程执行与父进程不同的程序,而不会创建新的进程。
它会从可执行程序中加载代码和静态数据,并用它复写自己的代码段,堆、栈及其他内存空间也会被重新初始化。
exec()替换程序后,成功调用不会返回。
#############################################
为什么这样设计API:
在UNIX shell中,分离fork()和exec()给了shell在fork之后,exec之前运行代码的机会。
eg.
p3.c通过exec()替换为wc,wc重定向到newfile.txt中。
shell重定向的过程:
子进程创建(fork)完成后,shell在exec()之前关闭标准输出,打开文件newfile,wc的输出结果发送到newfile上,而不是在屏幕中打印出来。
僵尸进程:
子进程比父进程先退出,导致子进程的PCB内容没被父进程回收。
解决办法:调用wait(),回收子进程的资源,获得子进程的最终状态。
孤儿进程:
父进程先于子进程结束,则子进程成为孤儿进程。
孤儿进程将被 init 进程(进程号为1)领养,并由 init 进程对孤儿进程完成状态收集工作。