一、什么是进程
进程:正在执行的程序,需要消耗内存和CPU资源。
进程与程序的区别:
- 程序是存放在硬盘上的静态指令集合;
- 进程驻留内存,运行需要CPU参与(内存+CPU);
- 进程拥有完整动态生命周期,从启动直到消亡;
- 运行一个程序可以产生一个或者多个进程;
- 一个进程内部也可以执行多个不同程序。
二、进程的创建
执行./a.out就会启动一个进程。 进程被创建时操作系统分配 0‑4G虚拟地址空间。
进程是操作系统资源分配的最小单位。
三、进程的调度
CPU调度:宏观并行,微观串行,实现并发
- 并行:多个任务同一时刻同时执行
- 并发:宏观看上去同时跑,微观交替执行
常见CPU调度算法:
- 时间片轮询算法
- 先来先服务算法
- 高优先级优先执行算法
- 短作业优先算法
四、进程的状态
基础三态模型:就绪态 → 运行态 → 等待态
Linux进程状态标识:
| 状态标识 | 状态名称 | 说明 |
|---|---|---|
| R | 运行/就绪态 | 正在被CPU执行;或者就绪等待CPU时间片 |
| S | 可唤醒等待态(睡眠) | 阻塞等待资源,可以被信号唤醒 |
| D | 不可唤醒等待态 | 不可被信号打断的睡眠,一般IO阻塞 |
| T | 暂停态 | 进程被暂停执行 |
| Z | 僵尸态 | 进程已经结束,但资源未被父进程回收 |
| X | 结束态 | 进程结束,资源已经回收 |
五、进程的消亡
两个环节:
- 进程退出
- 进程资源回收
六、进程相关命令
ps -aux查看全部进程:PID、创建者、状态、CPU、内存占用。
ps -aux | grep a.out
|管道:把前一条命令输出作为后一条输入;grep用于字符串过滤查找。
ps -ef查看PID、PPID(父进程ID)
- PID:进程ID
- PPID:父进程ID
- 父进程:创建子进程的进程
- 子进程:被创建出来的新进程
top动态实时刷新,查看进程、CPU、内存占用。pstree查看进程族谱父子关系。
pstree -sp 进程IDkill发送信号
kill -信号ID PID kill -l # 查看系统全部信号 kill -9 PID # 强制杀死进程jobs/fg
jobs:查看当前终端后台进程列表fg 后台编号:将后台进程调到前台运行
七、进程相关函数
1. fork 创建子进程
fork原理:拷贝父进程0‑3G用户空间给子进程;PCB内核部分拷贝;PID、PPID、程序执行位置、文件管理不拷贝。 父子进程共享3G‑4G内核空间;0‑3G用户空间相互独立,不能直接通信,进程间通信需要IPC机制。
#include <unistd.h> pid_t fork(void);返回值:
- 成功:父进程返回子进程PID;子进程返回 0
- 失败:返回
-1,不创建新进程
2. getpid / getppid
pid_t getpid(void); // 获取自己的PID pid_t getppid(void); // 获取父进程PID3. 进程退出方式
- 程序执行完毕自然退出
- main函数
return exit()/_Exit()- 接收信号退出(kill‑9)
#include <stdlib.h> void exit(int status); // status:0正常退出;非0异常退出 void _exit(int status); void _Exit(int status);4. 僵尸进程 & 孤儿进程
- 僵尸进程(Z):子进程已经结束,父进程尚未回收子进程资源。 避免方案:
- 父进程调用
wait/waitpid回收子进程 - 让子进程成为孤儿进程,交给系统进程回收
- 父进程调用
- 孤儿进程:父进程先退出,子进程被系统init进程收养,结束由系统自动回收,守护进程常用该机制。
5. wait 阻塞回收子进程
#include <sys/types.h> #include <sys/wait.h> pid_t wait(int *wstatus);- 参数:
wstatus接收子进程退出状态,不关心状态填NULL。 - 返回:成功返回被回收子进程PID;失败返回
‑1。 - 特点:阻塞等待,有僵尸子进程才返回。
使用示例:
wait(NULL);
6. waitpid 回收指定子进程
比wait更加灵活,支持非阻塞。
pid_t waitpid(pid_t pid, int *status, int options);pid参数
<-1:回收该进程组任意子进程-1:回收任意子进程(等价wait)0:回收同进程组的子进程>0:回收PID等于该值的指定子进程
options选项
0:阻塞模式WNOHANG:非阻塞,没有子进程可回收直接返回0
返回:
- 成功:子进程pid
- 无待回收子进程(WNOHANG)返回
0 - 出错返回
‑1
业务场景:父进程还要做别的任务,使用
WNOHANG轮询回收。
八、exec函数簇
作用:在现有进程内部执行外部可执行程序,替换进程代码段,PID不变。
| 函数 | 说明 |
|---|---|
execl() | 传入完整路径,参数列表形式传参 |
execlp() | 从PATH环境变量搜索程序,列表传参 |
execv() | 完整路径,argv数组传参 |
execvp() | PATH搜索程序,argv数组传参 |
execle() | 带自定义环境变量,列表传参 |
execvpe() | 带自定义环境变量,数组传参 |
字母含义:
l:list,参数列表逐个写v:vector,参数存入char*数组p:PATH,从环境变量路径查找程序e:传入自定义环境变量
int execl(const char *path, const char *arg, ... /* (char *) NULL */); int execlp(const char *file, const char *arg, ... /* (char *) NULL */); int execv(const char *path, char *const argv[]); int execvp(const char *file, char *const argv[]); int execle(const char *path, const char *arg, ... /*, (char *) NULL, char * const envp[] */); int execvpe(const char *file, char *const argv[], char *const envp[]);exec系列只有出错才有返回值,返回
‑1;执行成功不会返回。