前言
本篇笔记整理 Linux 应用编程核心三大模块:多进程、多线程、IPC进程间通信,是嵌入式 Linux、后端 C 开发的高频考点与工程常用技术,包含原理、函数接口、区别对比,同时补充易踩坑细节,适合期末复习、面试复盘。
一、多任务
多任务:让程序具备并发处理多个任务的能力,Linux 实现方式分为:多进程、多线程
1.1 什么是进程
程序:存放在硬盘上的静态指令集合( .c 编译后的可执行文件)
进程:正在运行的程序,加载进内存,占用内存、CPU 资源,拥有完整独立 0~4G 虚拟地址空间。

✅ 进程和程序核心区别
1.2 进程内存布局(0~4G虚拟空间)
分区 作用
内核空间(3G~4G) 操作系统内核代码、驱动、进程管理,所有进程共享
栈区(8M 默认) 局部变量、函数形参、函数返回地址,自动开辟释放
堆区 malloc/calloc/realloc 手动申请,必须手动 free 释放
.data段 初始化的全局变量、静态局部变量
.bss段 未初始化全局/静态变量,系统默认清零
文本区 代码指令、字符串常量,只读
💡 补充: fork() 创建子进程时,早期 Linux 使用完全拷贝,现代采用 写时拷贝(COW):父子进程先共享内存,任意一方修改数据时才单独复制内存副本,节省内存开销。
1.3 进程调度
CPU 宏观并行、微观串行(并发)
- 并行:多核 CPU,多个任务同时执行
- 并发:单核 CPU,时间片轮转,快速切换任务,宏观看起来同时运行
常见调度算法:
1.4 进程状态
经典三态模型
就绪态 →(分配CPU)运行态 →(时间片用完 / 请求IO)阻塞态
- 就绪:万事俱备,只等待 CPU 时间片
- 运行:正在被 CPU 执行
- 阻塞:等待IO资源( fgets 、 scanf ),主动放弃CPU
Linux 完整七状态
1.5 进程相关常用命令
bash
ps -aux # 查看所有进程,PID、状态、CPU/内存占用
ps -ef # 查看父子进程 PPID、PID
top # 实时监控进程资源占用
pstree -p # 树形查看父子进程关系
kill -9 PID # 强制杀死进程
kill -l # 查看所有信号
fg / bg # 前后台进程切换
1.6 进程核心函数
- 返回值:父进程返回子进程PID;子进程返回 0 ;失败返回 -1
- 作用:创建子进程,复制父进程用户空间,共享文件描述符
- exit() :刷新缓冲区,调用退出处理函数
- _exit() :直接退出,不刷新缓冲区
- wait() :阻塞等待任意子进程结束,回收僵尸进程
- waitpid() :灵活指定回收哪个子进程,支持非阻塞回收
1.7 僵尸进程 & 孤儿进程
✅ 危害:占用PID资源,大量僵尸会耗尽系统PID
✅ 解决:父进程调用 wait/waitpid ;或者父进程提前退出,让 init(1号进程) 收养回收
1.8 exec 函数族
execl / execlp / execv / execvp
作用:在当前进程内部,替换文本段为新程序,PID不变,不创建新进程
常用场景:fork 创建子进程后,子进程调用 exec 执行外部程序
二、线程
2.1 线程基础概念
线程:轻量级进程,是 CPU任务调度的最小单位
线程隶属于进程,一个进程至少有1个主线程。
同一个进程内所有线程共享:堆区、全局变量、文件描述符、.data/.bss/文本段
每个线程私有独立栈区(默认8M)
2.2 进程 VS 线程 对比表

对比项 进程 线程
资源属性 资源分配最小单位 CPU调度最小单位
创建开销 大,完整拷贝虚拟内存 极小,仅分配独立栈
内存隔离 完全独立,互不干扰 共享大部分内存,栈私有
通信方式 必须依靠IPC机制 直接读写全局变量(需要互斥锁保护)
安全性 高,进程崩溃互不影响 低,一个线程崩溃,整个进程全部退出
2.3 线程核心函数
⚠️ 编译线程代码必须加链接库: gcc test.c -o test -pthread
c
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
参数:线程ID地址、属性(NULL默认)、任务函数指针、传给任务函数的参数
返回:成功0,失败错误码
- pthread_join(thread, &retval) :阻塞等待线程结束,回收资源,默认非分离线程必须回收
- pthread_detach(tid) :设置分离属性,线程结束后由操作系统自动回收,不需要join
2.4 线程同步与互斥
互斥(竞争临界资源,保证同一时间只有一个线程访问)
临界资源:多个线程都能访问的资源(全局变量、文件)
临界区:访问临界资源的代码片段
工具:互斥锁 pthread_mutex_t
接口: pthread_mutex_init / lock / unlock / destroy
同步(控制线程执行先后顺序)
工具:信号量 sem_t
sem_init 初始化、 sem_wait(P-1申请) 、 sem_post(V+1释放)
2.5 死锁
死锁:多个线程互相持有对方需要的锁,互相等待,永久阻塞
✅ 死锁四大必要条件:互斥、持有并等待、不可剥夺、循环等待
✅ 解决思路:
三、IPC 进程间通信机制
IPC:Inter Process Communication,进程之间交换数据的机制
进程内存相互独立,不能直接访问对方内存,必须借助内核提供的IPC通道
IPC 分类
3.1 无名管道 pipe
- 适用范围:有亲缘关系进程(父子、兄弟)
- 原理:内核缓冲区,FIFO先进先出,半双工(单向通信)
- 函数: int pipe(int pipefd[2]);
- pipefd[0]:读端 read
- pipefd[1]:写端 write
✅ 管道4个特性:
3.2 有名管道 FIFO mkfifo
- 适用范围:同一主机任意进程(无亲缘限制)
- 特点:存在文件系统的管道文件,数据依然存内核缓冲区,文件仅作为访问入口
- 使用流程: mkfifo() 创建管道文件 → open打开 → read/write读写 → close关闭
3.3 信号 signal
信号:异步软中断,不携带大数据,仅传递通知事件
常见信号:
核心接口:
补充:信号处理规则
信号默认动作:终止进程、忽略、暂停;信号可以自定义捕获处理函数
3.4 System V IPC
(1)消息队列
内核维护链表,可以按消息类型收发数据,支持优先级读取
流程: ftok() 获取key → msgget() 创建队列 → msgsnd() 发送 → msgrcv() 接收 → msgctl() 删除队列
(2)共享内存(速度最快IPC)
原理:多个进程映射同一块内核内存到各自用户空间,不需要数据拷贝
注意:共享内存本身不带同步互斥,必须手动搭配信号量/互斥锁防止竞争访问
流程: shmget 创建 → shmat 映射挂载 → 直接读写内存 → shmdt 卸载 → shmctl 删除
(3)信号量集
多用于进程之间同步互斥,和线程sem信号量作用类似,支持多组信号量管理
3.5 Socket 套接字
既可以本机进程通信,也支持跨主机网络通信(TCP/UDP),是使用最广泛的IPC,后续网络编程重点学习。
四、学习总结 & 工程使用建议
- 父子简单单向通信:无名管道 pipe
- 本机任意进程简单通信:有名管道 fifo
- 异步事件通知:信号 signal
- 大量数据高速传输:共享内存(搭配信号量)
- 按类型分发消息:消息队列
- 跨主机通信:socket TCP/UDP
后续拓展:结合本次 TCP 客户端/服务端代码,完成多线程服务端、管道聊天程序、共享内存传输图片等综合实战项目。
网硕互联帮助中心






评论前必须登录!
注册