Linux进程控制(1)

1 进程创建

1-1 fork函数初识

在Linux中fork函数十分重要,它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。

复制代码
#include <unistd.h>
pid_t fork(void);
返回值:子进程返回0,父进程返回子进程id,出错返回-1

进程调用 fork ,当控制转移到内核中的 fork 代码后,内核做:

  • 分配新的内存块和内核数据结构给子进程
  • 将父进程部分数据结构内容拷贝至子进程
  • 添加子进程到系统进程列表当中
  • fork 返回,开始调度器调度

所以,fork之前父进程独立执行,fork之后,父子两个执行流分别执行。注意,fork之后,谁先执行完全由调度器决定。

1-2 写时拷贝

通常,父子代码共享,父子再不写入时,数据也是共享的,当任意一方试图写入,便以写时拷贝的方式各自⼀份副本。

因为有写时拷贝技术的存在,所以父子进程得以彻底分离!完成了进程独立性的技术保证!

写时拷贝,是⼀种延时申请技术,可以提高整机内存的使用率

1-3 fork常规用法

  • 一个父进程希望复制自己,使父子进程同时执行不同的代码段。例如,父进程等待客户端请求,生成子进程来处理请求。
  • 一个进程要执行一个不同的程序。例如子进程从 fork 返回后,调用 exec 函数。

1-4 fork调用失败的原因

  • 系统中有太多的进程
  • 系统用户的进程数超过了限制

2 进程终止

一、进程终止的三种情况

  1. 代码跑完,结果正确 进程正常执行完毕,逻辑和结果都符合预期,例如 main 函数 return 0
  2. 代码跑完,结果不正确 进程正常执行完毕,但结果不符合预期,例如 return 1(或其他非 0 退出码),表示程序逻辑错误。
  3. 代码没跑完,进程异常终止 进程中途被终止,例如收到信号(如段错误、被 kill 命令杀死),此时return没有被执行,退出码无意义。

二、进程退出状态的表示

进程的执行结果状态,由两个关键值表示:

  • sig(信号编号):表示进程是否因信号异常终止。sig == 0 表示正常结束;sig != 0 表示被信号终止。
  • exit_code(退出码):表示进程正常结束时的状态。只有当 sig == 0 时,退出码才有意义。
情况 sig(信号) exit_code(退出码)
正常且结果正确 0 0
正常但结果错误 0 非 0
异常终止 非 0 无意义

操作系统会把这两个信息写入进程的 task_struct(PCB)中,僵尸进程的核心作用,就是保存这个退出状态,供父进程读取

三、进程如何退出(不考虑异常)

  1. main 函数的 return

    • 只有 main 函数的 return 会让进程结束;其他函数的 return 仅表示函数调用结束。
    • return n 本质上等价于调用 exit(n)
  2. 在任意位置调用 exit()

    • 是 C 标准库函数,调用后进程直接终止。
    • 特点:会强制刷新缓冲区 (把缓冲区数据写入文件 / 终端),再调用系统调用 _exit()
  1. 在任意位置调用 _exit()

    • 是直接的系统调用,内核提供的接口。
    • 特点:直接终止进程,不会刷新缓冲区,也不做任何用户态的清理工作。

💡 关键对比:exit() 会刷新缓冲区,_exit() 不会。因为缓冲区和刷新操作是 C/C++ 库维护的,不是内核的功能。

四、内核视角:进程终止时的操作

  1. 进程退出时,操作系统会将退出状态(exit_codesig)写入进程的 task_struct
  2. 进程需要以僵尸进程 的形式保留 PCB,直到父进程通过 wait()/waitpid() 读取退出状态,才会被彻底回收
相关推荐
A小辣椒14 小时前
TShark:Wireshark CLI 功能
linux
A小辣椒18 小时前
TShark:基础知识
linux
AlfredZhao20 小时前
OCI 明明分配了 200G 系统盘,为什么 df 只看到 30G?
linux·oci
AlfredZhao1 天前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334662 天前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪2 天前
linux 拷贝文件或目录到指定的位置
linux
大树882 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠2 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质2 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
bush42 天前
嵌入式linux学习记录十四、术语
linux·嵌入式