进程控制:进程创建/进程终止/进程等待/程序替换
进程创建:
fork函数
pid_t fork(void)
返回值:
子进程中返回==0
父进程返回子进程pid >0
出错返回 <0
会根据返回值对父子进程所运行的代码进行分流。
流程:clone()
- 1.创建pcb:创建子进程,子进程复制父进程,因此与父进程运行的代码和数据看起来都一样,因为子进程的虚拟地址空间和页表都和父进程一样。因此父子进程映射后,指向的都是同一块物理内存。
- 2.复制信息:子进程复制了父进程的程序计数器/上下文数据,因此连当前的运行位置都一样
- 3.若原物理内存中数据发生改变,为了保证进程独立性,因此给子进程重写开辟物理内存,拷贝数据(写时拷贝技术:提高子进程的创建效率)
pid_t vfork(void)
早期为了提高子进程的创建效率而设计的接口,现在不常用。
创建一个子进程,父子进程共用同一个虚拟地址空间。使用同一个栈,两个进程同时运行会造成调用栈混乱,阻塞父进程。
因此父进程调用vfork创建子进程,会被阻塞,直到子进程exit()退出/进行了程序替换,重新创建了自己的虚拟地址空间之后,父进程才会vfork返回继续运行。
子进程不能在main函数中使用return退出,因为会释放所有资源。
进程终止:
进程退出的场景:
正常退出,结果符合预期
正常退出,结果不符合预期
异常退出,结果不能作为判断基准
进程的返回值,只用了一个字节来保存
进程常见退出方法:
-
正常终止:
1.mian函数中的return
2.void_exit(int status):系统调用接口 2号手册
3.void exit(int status):库函数3号手册
前两种退出一个进程时,会刷新缓冲区。第三种则不会刷新。 -
进程的退出码:只用一个字节来保存,范围0~255
-
异常退出:
ctrl + c,信号终止
系统调用接口使用失败时的错误信息:
perror/strerror(errno)
进程等待
等待子进程退出,获取子进程的返回值,允许操作系统释放子进程资源,避免产生僵尸进程
如何等待:
1.wait方法:
pid_t wait(int *stauts);--阻塞函数</