一、进程基础

1. 进程与程序的区别

        程序:是静态的代码和数据集合,不占用CPU和内存资源。

        进程:是程序的动态执行过程,会占用CPU、内存等系统资源,具有独立的地址空间。

2. 进程的标识与查看

ps 是查看进程的核心命令

ps -f :显示进程的详细信息,包括:

        PID :进程ID(唯一标识进程)

        UID :进程所属用户ID

        PPID :父进程ID

        C :CPU占用率

        STIME :进程启动时间

        TTY :进程所属终端

        CMD :启动进程的命令

ps -e :显示系统中所有进程

ps -ef :显示所有进程的完整格式信息

二、进程生命周期管理

1. 进程创建

 fork() 是Linux中创建子进程的核心系统调用

        返回值:父进程返回子进程的PID,子进程返回 0 ,出错返回 -1 (如内存不足、系统进程数上限)。

        地址空间:子进程复制父进程的地址空间(代码段、数据段、堆、栈等),但现代Linux采用写时拷贝,仅在子进程修改内存时,才实际复制对应的内存页,减少资源浪费。

2. 进程终止

        exit() (标准库函数):先执行用户态资源清理(如刷新缓冲区),再通知内核终止进程。

        _exit() (系统调用):直接通知内核终止进程,不执行用户态清理操作。

        适用场景:普通单进程程序优先用 exit() ;多进程(如父子进程)中子进程优先用 _exit() ,避免父进程资源被意外清理。

3. 进程等待

        wait() :阻塞等待任意一个子进程终止。

        waitpid() :可指定等待的子进程(通过PID),支持非阻塞轮询。

        作用:父进程通过 wait() 或 waitpid() 回收子进程资源,避免子进程成为“僵尸进程”(子进程终止后,父进程未回收其PCB,导致资源泄漏)。

三、进程管理

1. 进程前后台切换

        Ctrl+Z :暂停前台进程,将其放入后台暂停态

        jobs :查看后台进程列表

        fg %进程编号 :将后台进程调至前台运行

        bg %进程编号 :将后台暂停的进程恢复为后台运行

        nohup 命令 & :启动进程并忽略挂起信号,确保进程在终端关闭后仍能后台运行

2. 进程终止与信号

        kill PID :向进程发送终止信号(默认 SIGTERM ),进程可捕获信号并优雅退出

        kill -9 PID :发送强制终止信号( SIGKILL ),进程无法捕获,直接被终止

        killall 进程名 :终止所有同名进程

四、进程替换

 exec 函数族用于替换当前进程的映像,让进程执行另一个程序

        特点:若 exec 调用成功,当前进程的代码段、数据段、堆、栈会被新程序替换,且进程PID保持不变;若调用失败,返回 -1 并设置 errno 。

        应用场景:实现“命令解释器”(如 Mybash )——父进程读取用户命令,创建子进程后通过 exec 执行命令。

五、进程进阶

1. 命令行参数

C程序的 main 函数支持命令行参数,格式为:int main(int argc, char *argv[], char *envp[])

        argc :命令行参数总个数

        argv :字符串数组,存储每个参数的具体内容( argv[0] 是程序名)

        envp :字符串数组,存储系统环境变量(如 PATH 、 HOME )

2. 进程地址空间

Linux为每个进程维护独立的虚拟地址空间(32位系统为4GB)

        内核空间(1GB):运行内核代码,普通进程无权限访问。

        用户空间(3GB):分为代码段、数据段、堆、栈等区域,进程仅能访问自己的用户空间。

3. 系统调用

进程通过系统调用(如 fork 、 exit 、 exec )向内核请求服务。系统调用的执行流程:

        1. 进程触发软中断

        2. 内核捕获中断,切换到内核态

        3. 执行对应的内核函数,完成请求

        4. 切换回用户态,返回进程继续执行

 

 

 

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐