进程的消亡

进程退出

  1. 在主函数中return;
  2. exit(),库函数,直接结束一个进程,结束前会刷新缓冲区
  3. _exit(), _Exit(),系统调用,直接结束一个进程,结束前不会刷新缓冲区
  4. 被动退出:异常退出、使用signal结束一个进程(kill)

回收进程空间

僵尸进程:子进程结束后,父进程没有回收子进程的资源空间,此时,该子进程成为僵尸进程。

如何避免僵尸进程:

  1. 子进程结束,由其父进程回收资源空间
  2. 让子进程成为一个孤儿进程

孤儿进程 :父进程先结束,其父进程创建的子进程成为孤儿进程,将会被系统进程收养,结束时由系统进程回收。

  • 进程空间回收策略:

    1.对于一直处于运行状态,不会结束的进程不需要回收

    2.进程在执行有结束的情况时回收

  • 进程资源空间回收:

    wait
    wait 是父进程用于回收子进程资源、获取子进程退出状态的核心系统调用。

  • wstatus 是一个输出参数,存储子进程的退出状态信息

waitpid

pid 参数的含义

pid 值 含义
> 0 等待指定 PID 的子进程
-1 等待任意子进程(同 wait)
0 等待同进程组的任意子进程
< -1 等待进程组 ID = |pid| 的任意子进程

options 参数

选项 含义
0 阻塞等待
WNOHANG 非阻塞,如果没有子进程结束立即返回 0
WUNTRACED 也返回因信号而停止的子进程状态
WCONTINUED 也返回因信号而恢复的子进程状态

等待特定子进程

pid_t pid1 = fork();  // 重要任务
pid_t pid2 = fork();  // 次要任务

if (pid1 > 0) {
    int wstatus;
    // 只等待重要的子进程
    waitpid(pid1, &wstatus, 0);
    printf("重要任务已完成\n");
    
    // 次要任务可以继续运行,或者后面再等
}

非阻塞检查(轮询)

pid_t pid = fork();
if (pid == 0) {
    sleep(5);  // 长任务
    exit(0);
}

int wstatus;
int count = 0;
while (1) {
    pid_t ret = waitpid(pid, &wstatus, WNOHANG);
    
    if (ret == pid) {
        printf("子进程完成,检查了 %d 次\n", count);
        break;
    } 
    else if (ret == 0) {
        printf("第 %d 次检查:子进程还在运行\n", ++count);
        sleep(1);
    } 
    else {
        perror("waitpid error");
        break;
    }
}

exec函数

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐