深入理解Linux进程控制(代码+图解)


前言
本专栏知识点是通过 零声教育 的线上课学习,进行梳理总结写下文章,对c/c++linux课程感兴趣的读者,可以点击链接 C/C++后台高级服务器课程介绍 详细查看课程的服务。
一.进程创建
1.fork()
让正在运行的程序创建出来一个子进程,它从已存在的进程中创建一个新进程,新进程为子进程,而原进程为父进程。
返回值:pid_t
创建失败:返回-1;
创建成功:
大于0:返回给父进程
等于0:返回给子进程
2.fork的工作内容
创建子进程,子进程拷贝父进程的PCB
1):分配新的内存块和内核数据结构(task_struct)给子进程
2):将父进程部分数据结构内容拷贝至子进程
3):添加子进程到系统进程列表当中,添加到双向链表中
4):fork返回,开始调度器(操作系统开始调度)调度
3.用户控件&内核空间
内核空间:Linux操作系统和驱动程序运行在内核空间。即系统调用函数都是在内核空间运行的,因为是操作系统提供的函数。
用户空间:应用程序都是运行在用户空间的。即自己写的代码都是运行在用户空间的。
但是,当程序员的代码调用了系统调用函数,则会切换到内核空间执行。执行完毕之后,再返回到用户空间继续执行用户代码。
4.写时拷贝
在父进程创建出子进程后,子进程的PCB是拷贝父进程的,页表也是拷贝父进程的,在刚开始,同一变量的虚拟地址和物理地址的映射关系是一样的,操作系统并没有给子进程的变量在物理内存中分配空间,子进程的变量还是原来父进程中物理地址中的内容。
当数据进行改变时:以写时拷贝的方式进行拷贝一份,此时父子进程通过各自的页表,指向不同的物理地址。
当数据不发生改变:父子进程共享同一个数据。
5. fork的用法
守护进程:
父进程创建子进程,让子进程执行真正的业务(进程程序替换),父进程负责守护子进程。
当子进程在执行业务时出现问题,父进程负责重新启动子进程,让子进程继续提供服务。
相关视频推荐
红黑树在linux内核中的3种场景(红黑树证明,进程管理CFS,内存管理)
【文章福利】:小编整理了一些个人觉得比较好的学习书籍、视频资料共享在群文件里面,有需要的可以自行添加哦!~ 点击832218493加入 (需要自取)
二.进程终止
1.进程终止的场景
进程终止可分为三种
代码运行结束,结果正确;
代码运行结束,结果不正确;
代码异常终止;
正常终止:
从main函数的return返回只有main函数的return才能结束程序
调用exit函数(库函数)
#include<stdlib.h>
作用:谁调用终止谁
其中status为程序退出的退出码( 可以用echo $?查看进程退出码)
调用_Exit函数(系统调用函数)
#include<stdlib.h>
作用:谁调用终止谁
异常终止: 异常终止即程序崩溃
可能导致其的原因有:ctrl+c,内存访问越界,访问空指针
2.exit和_Exit的区别
exit函数比_exit函数多执行两个步骤
1.执行用户自定义的清理函数
2.冲刷缓冲区,关闭流等
3.调用进程(_Exit);(exit函数的实现也调用了_Exit函数)
3.自定义清理函数
回调函数:在代码中注册一个函数,在特定的时候进行执行
#include<stdlib.h>
#include<stdio.h>
void atexit_callback(void)
printf("i am atexit_callback\n");
int main()