【Linux内核设计与实现】第三章——进程管理04
文章目录
- 8. exit() 进程退出
- 8.1. exit() 系统调用的定义
- 8.2. do_exit() 函数
- 8.2.0. do_exit() 的参数和返回值
- 8.2.1. 检查和同步线程组退出
- 8.2.2. 清理与调试相关的资源
- 8.2.3. 取消 I/O 和信号处理
- 8.2.4. 检查线程组是否已终止
- 8.2.5. 释放系统资源
- 8.2.6. 释放线程和调度相关资源
- 8.2.7. 通知父进程
- 8.2.8. 减少进程栈引用计数,设置进程状态 DEAD 并切换进程
- 8.2.9. 进程消亡
- 8.2.10. put_task_stack() 释放内核栈
- 8.2.11. release_task_stack()
- 8.2.12. free_thread_stack()
- 8.2.13. thread_stack_delayed_free()
- 8.2.14. thread_stack_free_rcu()
- 8.2.15. try_release_thread_stack_to_cache()
- 8.3. do_exit() 函数小结
- 9. 阻塞等待退出
- 9.1. wait 系统调用
- 9.2. 核心数据结构 struct wait_opts
- 9.3. do_wait()
- 9.3.1 初始化等待队列
- 9.3.2 进入等待循环
- 9.3.3. 恢复运行状态
- 9.3.4. 返回结果
- 9.4. __do_wait()
- 9.4.1. 处理不同的等待类型
- 9.4.2. 处理无匹配子进程的情况
- 9.4.3. 返回结果
- 9.5. wait_consider_task()
- 9.5.1. 函数参数
- 9.5.2. 检查子进程的退出状态
- 9.5.3. 检查子进程是否符合等待条件
- 9.5.4. 处理 `EXIT_TRACE` 状态
- 9.5.5. 处理被 `ptrace` 跟踪的子进程
- 9.5.6. 处理 `EXIT_ZOMBIE` 状态
- 9.5.7. 处理其他状态
- 9.5.8. 等待停止状态
- 9.5.9. 等待继续状态
- 9.6. wait_task_zombie()
- 9.6.1. 函数参数
- 9.6.2. 主要工作流程
- 9.7. release_task()
- 9.7.1. 函数参数
- 9.7.2. 初始化清理状态
- 9.7.3. 减少进程计数
- 9.7.4. 释放与进程相关的子系统资源
- 9.7.5. 获取线程 PID
- 9.7.6. 加锁并清理信号和调试信息
- 9.7.7. 处理线程组领导者
- 9.7.8. 释放 PID 和其他资源
- 9.7.9. 清理信号队列
- 9.7.10. 释放任务结构
- 9.7.11. 处理线程组领导者的释放
- 9.8. put_task_struct_rcu_user()
- 9.8.1. put_task_struct_rcu_user 的作用
- 9.8.2. delayed_put_task_struct 的作用
- 9.9. put_task_struct()
- 9.9.1. 函数定义
- 9.9.2. 函数参数
- 9.9.3. 减少引用计数
- 9.9.4. 检查是否可以直接释放
- 9.9.5. 延迟释放(针对 `PREEMPT_RT`)
- 9.9.5. 延迟释放(针对 `PREEMPT_RT`)
- 9.9.6. 延迟释放的回调函数 `__put_task_struct_rcu_cb`
- 9.10. __put_task_struct()
- 9.10.1. 函数定义
- 9.10.2. 函数参数
- 9.10.3. 检查进程状态
- 9.10.4. 释放调度相关资源
- 9.10.5. 释放 I/O 相关资源
- 9.10.6. 释放控制组(cgroup)资源
- 9.10.7. 释放 NUMA 相关资源
- 9.10.8. 释放安全模块相关资源
- 9.10.9. 释放进程凭据
- 9.10.10. 释放延迟统计资源
- 9.10.11. 释放信号相关资源
- 9.10.12. 释放任务描述符
- 9.11. 最终释放 free_task()
- 9.11.1. 函数定义
- 9.11.2. 函数参数
- 9.11.3. 检查 Seccomp 过滤器
- 9.11.4. 释放内核相关资源
- 9.11.5. 释放任务栈
- 9.11.6. 释放相关调试信息
- 9.11.7. 释放架构特定的任务结构
- 9.11.8. 释放内核线程结构
- 9.11.9. 释放 BPF 任务存储
- 9.11.10. 释放任务描述符
- 10. 进程退出为什么延时销毁?
- 11. 遗留问题
- #上一篇
- #下一篇
[注]:本篇文章与上一篇紧密相关,若未阅读上一篇请移步上一篇阅读,在文末可以找到上一篇链接。
8. exit() 进程退出
在了解完进程的创建流程后,我们也应该学习一下一个进程是如何退出操作系统的。相信大家都知道 exit()
系统调用,就是用来终止一个进程。它会清理进程的资源、通知父进程,并最终将进程从系统中移除。接下来就来仔细分析该函数。
8.1. exit() 系统调用的定义
exit()
系统调用的实现如下:
// Linux Kernel 6.15.0-rc2
// PATH: kernel/exit.c
SYSCALL_DEFINE1(exit, int, error_code