学习笔记——Linux 进程管理笔记

inux 进程管理笔记

一、父子进程关系

1. 进程复制机制

  • 子进程是父进程的副本

  • Linux 2.6之后(如Ubuntu 18,Linux 5.4) :采用**写时复制(Copy-On-Write,COW)**技术

  • fork完成后:子进程共享父进程的所有内存空间

  • 写时复制触发时机:当父子进程中的任何一方尝试修改某个变量或内存区域时,才会为子进程开辟新的内存空间

2. 进程终止的8种情况

正常终止:
  1. main函数中的return

  2. exit() - C库函数

    • 执行I/O库的清理工作

    • 关闭所有流和已打开的文件

    • 执行清理函数(atexit注册的函数)

  3. _exit() / _Exit() - 系统调用

    • 关闭所有已打开的文件

    • 不执行清理函数

  4. 主线程退出

  5. 主线程调用pthread_exit()

异常终止:
  1. abort() - 产生SIGABRT信号

  2. 信号终止 - signal/kill发送信号

  3. 最后一个线程被pthread_cancel()

二、进程退出后的状态

1. 僵尸进程(Zombie)

  • 产生条件:子进程先于父进程终止

  • 状态特征

    • 用户内存空间已释放

    • 进程不会被调度执行

    • 但内核中的PCB(进程控制块)未被释放

  • 危害:长时间运行的父进程多次创建子进程时,可能导致内核空间积累大量僵尸进程PCB,引发系统不稳定或崩溃

  • 查看命令pstop

2. 孤儿进程(Orphan)

  • 产生条件:父进程先于子进程终止

  • 处理机制

    • 子进程会被init进程(PID=1)接管

    • 由新的父进程(init)负责回收资源

    • 通常无需特别关注

三、退出函数详解

1. exit() - 库函数

复制代码
void exit(int status);
  • 功能:让进程退出,并刷新缓冲区

  • 参数

    • status:进程退出状态

    • 常用值:EXIT_SUCCESS(0)、EXIT_FAILURE(1)

  • 执行流程

    • 刷新缓冲区

    • 执行atexit()注册的退出函数

    • 调用_exit()系统调用

2. _exit() - 系统调用

复制代码
void _exit(int status);
  • 功能 :让进程退出,不刷新缓冲区

  • 参数status - 进程退出状态

3. return关键字的区别

  • 在main函数中:结束整个进程

  • 在其他函数中:仅结束当前函数

四、进程状态回收

1. wait()函数

复制代码
pid_t wait(int *status);
  • 功能:阻塞等待任意子进程退出,并回收其状态

  • 特点

    • 只能由父进程调用

    • 一次只能回收一个子进程

  • 参数

    • status:存储子进程退出状态

    • 不关心状态时可传入NULL

  • 返回值

    • 成功:回收的子进程PID

    • 失败:-1

2. 状态检查宏

功能 说明
WIFEXITED(status) 检查是否正常终止 返回非0表示正常结束
WEXITSTATUS(status) 获取退出状态值 正常终止时使用
WIFSIGNALED(status) 检查是否信号终止 返回非0表示信号终止
WTERMSIG(status) 获取终止信号编号 信号终止时使用

3. 使用示例

复制代码
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
    pid_t pid = fork();
    
    if (pid == 0) {
        // 子进程
        exit(42);  // 正常退出,状态码42
    } else {
        // 父进程
        int status;
        wait(&status);
        
        if (WIFEXITED(status)) {
            printf("子进程正常退出,返回值:%d\n", 
                   WEXITSTATUS(status));  // 输出:42
        }
        if (WIFSIGNALED(status)) {
            printf("子进程被信号终止,信号:%d\n",
                   WTERMSIG(status));
        }
    }
    return 0;
}

五、进程空间回收的重要性

1. 僵尸进程的危害

  • 内核PCB空间被占用,无法释放

  • 大量僵尸进程可能导致内核内存不足

  • 影响系统稳定性和性能

2. 回收策略

  • 父进程应主动调用wait()waitpid()回收子进程

  • 对于需要多次创建子进程的服务进程,必须正确回收

  • 可使用信号处理函数(如SIGCHLD)异步回收

六、总结要点

  1. 写时复制是现代Linux的优化机制,减少不必要的内存复制

  2. 区分正常终止与异常终止的不同处理方式

  3. exit()和_exit()的主要区别在于缓冲区刷新和清理函数执行

  4. 僵尸进程需要父进程主动回收,否则会长期占用系统资源

  5. wait()系列函数是进程回收的标准方法

  6. 状态检查宏帮助父进程了解子进程的终止原因

注意事项

  • 在生产环境中,应确保所有子进程都被正确回收

  • 对于服务器程序,建议设置SIGCHLD信号处理

  • 使用waitpid()可以更灵活地控制回收行为(如非阻塞模式)

相关推荐
还不秃顶的计科生17 分钟前
具身智能论文学习8:Octo: An Open-Source Generalist Robot Policy
人工智能·深度学习·学习·机器学习·语言模型·vla·vlm
woshihuanglaoshi42 分钟前
事务加持防超卖:ArkTS 在鸿蒙里玩转 TRANSACTION 出入库
学习·华为·harmonyos
qeen8743 分钟前
【数据结构】自平衡二叉搜索树各种旋转算法原理解析及AVL树的C++实现
数据结构·c++·算法
x²+(y-√³x²)²=11 小时前
Linux打包文件到Windows,文件/文件类型丢失
linux·运维·windows
世人万千丶1 小时前
去重插入与超限淘汰:ArkTS 实现鸿蒙搜索历史的 LIMIT 艺术
运维·服务器·学习·华为·harmonyos·鸿蒙
lucas_AI1 小时前
1.2B 小模型赢过 235B 大模型:NaviDC-OCR 把文档解析卷明白了
人工智能·深度学习·算法
柒号华仔1 小时前
「速通Shell」聚砖成墙,Shell函数封装之道
linux·ssh·bash
未来之窗软件服务1 小时前
企业自动化运营-电子合同预览-东方仙盟
运维·自动化·仙盟创梦ide·东方仙盟
程序员与背包客_CoderZ1 小时前
Linux D-Bus通信协议详解:从入门到C/C++编码实战
linux·服务器·c语言·c++·嵌入式硬件·嵌入式软件·dbus
Android系统攻城狮1 小时前
Linux PipeWire深度解析之pw_properties_iterate调用流程与实战(六十五)
linux·运维·服务器·音频进阶·pipewire音频进阶