一、Linux 进程管理
1. 进程基础概念
- 操作系统(以 Ubuntu 为例)会为每个进程分配唯一的 PID 号(取值范围 0 到系统上限)。
- 进程控制块:进程号理论上连续,若出现不连续情况,说明中间进程已结束并释放资源。
- 父进程PPID与子进程PID:二者关系是相对的,子进程由父进程创建。
2. 进程查看指令
| 指令 | 功能 |
|---|---|
ps |
打印当前终端中的进程 |
ps -e |
打印当前系统中的所有进程 |
ps -f |
打印当前终端中进程的详细信息 |
ps -ef |
打印当前系统中进程的更多属性(包含 UID、PID、PPID、TTY、CMD 等) |
ps -l |
显示系统中的线程 |
3.进程属性说明:
| 指令 | 功能 |
| UID | 运行该进程的用户名 |
| PID | 进程号 |
| PPID | 该进程的父进程号 |
| TTY | 终端号 |
| CMD | 进程名称(如bash为命令解释器) |
|---|
4. 进程控制指令
| 操作 | 指令 | 说明 |
|---|---|---|
| 进程休眠 | sleep 秒数 |
让进程休眠指定秒数 |
| 杀死进程 | kill 进程号 |
终止前台 / 后台进程(进程暂停时需用kill -9 进程号强制杀死) |
| 结束前台进程 | Ctrl + c |
强制终止当前前台运行的进程 |
| 暂停进程 | Ctrl + z |
将前台进程暂停 |
| 后台运行进程 | 指令 & |
如sleep 300 &,让进程在后台运行 |
| 查看后台任务 | jobs |
列出当前后台运行的任务 |
| 后台任务切前台 | fg %任务号 |
如fg %1,将编号为 1 的后台任务切到前台 |
| 暂停任务切后台 | bg %任务号 |
如bg %1,将暂停的任务切换到后台继续运行 |
5. 后台进程拓展示例
后台循环执行指令:
//每隔 2 秒打印当前时间,后台持续运行
while true;do date;sleep 2;done &;
后台进程输入规则:后台进程输出不影响命令行输入,只要命令行未提交,仍可继续输入指令。
二、GCC 编译与程序构建
1. 可执行文件格式
- Linux 系统:ELF 格式;
- Windows 系统:PE 格式。
2. GCC 分步编译流程
| 阶段 | 指令 | 输出文件 | 文件类型 |
|---|---|---|---|
| 预编译 | gcc -E main.c -o main.i |
main.i | 预处理文件 |
| 编译 | gcc -S main.i -o main.s |
main.s | 汇编文件 |
| 汇编 | gcc -c main.s -o main.o |
main.o | 二进制目标文件 |
| 链接 | gcc main.o -o main |
main | 可执行文件 |
3. 多文件编译
将多个
.c文件编译为可执行文件:gcc file1.c file2.c -o app;或先编译为
.o文件再链接:gcc -c file1.c -o file1.o && gcc -c file2.c -o file2.o && gcc file1.o file2.o -o app。
4. Makefile 与 make
- 作用:自动化构建(编译代码、链接程序、清理中间文件),适用于多文件 / 多模块大型项目;
- 执行规则:若 Makefile 包含自定义指令,需通过
make + 指令标志位执行。
三、GDB 调试
1. 编译版本区分
- Debug 版本:含调试信息,开发用,编译指令
gcc -g 源文件 -o 可执行文件; - Release 版本:发行给用户,无调试信息,
gcc默认生成该版本。
2. 核心调试指令
| 指令 | 功能 |
|---|---|
gdb 可执行文件名 |
进入调试模式 |
l |
显示代码内容 |
b 行号 |
在指定行下断点 |
r |
运行调试程序 |
p 变量名 |
打印变量值 |
delete 断点号 |
删除指定断点 |
q |
退出调试 |
四、库文件使用
1. 库文件基础
- 本质:预先编译好的方法集合;
- 头文件查找:
<头文件>从系统库查找,"头文件"从当前目录查找; - 库类型:静态库(
libxxx.a)、动态库(libxxx.so)。
2. 静态库操作
- 生成:
ar crv 库名.a 文件1.o 文件2.o; - 编译可执行文件:
gcc -o 可执行文件 源文件.c -L. -l库名(如gcc -o main main.c -L. -lfoo)。
3. 动态库操作
- 生成:
gcc -shared -fPIC -o libfoo.so add.o max.o(-shared生成动态库,-fPIC生成位置无关代码); - 编译可执行文件:
gcc main.c -o main -L. -lfoo; - 运行问题解决:
- 查看库链接情况:ldd
可执行文件名; - 动态库路径配置:
- 方法 1:将动态库移至
/usr/lib(系统标准库路径); - 方法 2:设置环境变量
LD_LIBRARY_PATH=动态库绝对路径,并执行export LD_LIBRARY_PATH启用;
- 方法 1:将动态库移至
- 查看库链接情况:ldd
- 权限问题:指令前加
sudo临时获取管理员权限,或切换管理员身份执行。
4. 静态库与动态库对比
| 维度 | 静态库 | 动态库 |
|---|---|---|
| 可执行文件依赖 | 删除库后仍可运行 | 删除库后无法运行 |
| 可执行文件体积 | 较大(拷贝库代码) | 较小(仅记录依赖) |
| 编译阶段 | 拷贝库中被引用代码到可执行文件 | 仅记录依赖,不拷贝代码 |
| 链接时机 | 编译时链接,完成后不依赖库 | 运行时链接,依赖库存在 |
| 资源占用 | 磁盘 / 内存占用高(多程序重复拷贝) | 资源占用低(多程序共享) |
| 更新维护 | 库更新需重新编译所有依赖程序 | 接口兼容时,替换库即可,无需重编译 |
| 使用场景 | 独立运行程序、嵌入式设备、小型工具 | 系统级库、大型应用、需频繁更新的场景 |
五、内存与存储
源文件(如main.c)保存在硬盘中; 可执行文件运行时,会被装载到内存中,仅运行时才占用内存资源。