#Linux 应用开发 #文件 IO #多进程 #多线程 #IPC 进程间通信
前言
本篇基于 Linux 应用编程学习文档整理,覆盖嵌入式 Linux 应用开发四大核心板块:文件操作、多任务(进程、线程)、线程同步互斥、IPC 进程间通信。重点区分标准 C 库标准 IO 与 Linux 内核文件 IO 系统调用,理清进程、线程底层内存模型,梳理全套常用 API、使用场景以及典型问题(僵尸进程、孤儿进程、死锁),适合课后复习、面试速查。
一、Linux 文件操作
1. 内存与文件对比
内存:读写速度快;程序结束 / 掉电数据丢失;空间小价格昂贵。 文件 (外存硬盘):读写速度慢;断电数据持久保存;存储空间大,成本低。
Linux 一切皆文件,共 7 种文件类型,ls -l首字符区分:
-普通文件:文本 ASCII 文件、二进制文件d目录文件:文件夹c字符设备文件:鼠标、键盘b块设备文件:硬盘l软链接:快捷方式ssocket 套接字:网络编程ppipe 管道:进程间通信
2. 标准 IO(C 库函数,FILE* 文件流指针)
头文件stdio.h,固定流程:打开→读写→关闭。
fopen()打开文件,模式r/r+/w/w+/a/a+- 读写接口
fgetc/fputc:单字符读写fgets/fputs:按行读写,适合文本文件,不能处理二进制\0fread/fwrite:块读写,支持二进制文件
fclose()关闭文件,避免文件描述符泄露。
系统预定义 3 个流:stdin标准输入、stdout标准输出、stderr标准错误输出。
流定位接口:fseek偏移、ftell获取当前偏移、rewind回到文件头部,可用来计算文件大小。
用户缓冲区分类
- 行缓冲 :大小 1K,终端设备;
\n、fflush、缓冲区满、程序结束触发刷新。 - 全缓冲:大小 4K,普通磁盘文件;缓冲区满、关闭文件、fflush 强制刷新。
- 无缓冲:stderr,直接输出,不缓存。
3. 文件 IO(系统调用,文件描述符 fd)
内核提供系统调用,头文件sys/types.h sys/stat.h fcntl.h unistd.h
open()打开文件;flags:O_RDONLY、O_WRONLY、O_RDWR、O_CREAT、O_TRUNC、O_APPEND;mode 设置新建文件权限。read()读取数据、write()写入数据、close()关闭。lseek()修改文件读写偏移位置。
文件描述符规则:0~1023,遵循最小未使用分配;0、1、2 默认分别对应标准输入、输出、错误。
标准 IO 和 文件 IO 对比
表格
| 对比维度 | 标准 IO | 文件 IO |
|---|---|---|
| 操作句柄 | FILE*文件流指针 |
int 文件描述符 fd |
| 接口来源 | C 标准库函数 | Linux 内核系统调用 |
| 可移植性 | 跨平台,可移植性强 | Linux 专属,移植弱 |
| 缓冲区 | 带用户层缓冲区,减少系统调用 | 无用户层缓冲,实时性高 |
| 适用场景 | 普通文件读写 | 硬件设备文件操作 |
4. 目录 IO
opendir()打开目录 → readdir()读取目录项信息struct dirent → closedir()关闭目录; mkdir()创建目录。
5.framebuffer 帧缓冲
/dev/fb0显示设备文件,使用mmap内存映射,把显存映射至用户空间,直接写 RGB 数值完成屏幕绘图。
6. 时间与日志编程
time()获取 1970 至今秒数;ctime()、localtime()把秒数转为时间格式。 日志模块封装:init_log()初始化、write_log(等级,字符串)写日志(INFO/WARNING/ERROR)、deinit_log()关闭日志;进阶功能:按日期生成日志文件。
二、多任务编程:进程、线程
进程:操作系统资源分配最小单位 ;线程:CPU任务调度最小单位
1. 进程
程序是硬盘上静态指令集合;进程是程序运行实例,占用内存 CPU,拥有独立 0‑4G 虚拟地址空间。
fork()创建子进程 父进程返回子进程 PID,子进程返回 0,失败返回‑1;子进程拷贝父进程用户空间,内核空间共享。 辅助 API:getpid()获取自身 PID,getppid()获取父进程 PID。- 进程退出方式:return、
exit()、_exit()、接收信号终止。 - 僵尸进程、孤儿进程
- 僵尸进程:子进程退出,父进程没有回收资源;使用
wait()/waitpid(WNOHANG)进行回收。 - 孤儿进程:父进程提前结束,子进程被系统进程收养,退出资源自动回收。
- exec 函数族:在当前进程运行新程序,替换进程代码段。
execl/execlp/execv/execvp;l列表传参,p从 PATH 环境变量搜索程序。 - Linux 进程状态:R 运行、S 可中断睡眠、D 不可中断睡眠、T 暂停、Z 僵尸、X 完成回收。
2. 线程(轻量级进程)
线程隶属于所属进程;共享进程堆、数据段、代码段;每个线程拥有独立栈空间。编译链接添加‑pthread。
pthread_create()创建线程- 线程回收
- 非分离属性(默认):
pthread_join()阻塞等待回收线程资源。 - 分离属性:
pthread_detach(),线程结束操作系统自动回收,无需 join。
3. 线程互斥与同步
- 互斥锁 pthread_mutex_t :解决多线程临界资源竞争;流程:
pthread_mutex_init初始化 →lock加锁 →unlock解锁 →destroy销毁。 - 信号量 sem_t :实现线程同步;P 操作
sem_wait()资源‑1;V 操作sem_post()资源 + 1。
4. 死锁
死锁 4 个必要条件:互斥、请求与保持、不可剥夺、循环等待;破坏任意一条即可解除死锁。
三、IPC 进程间通信
IPC 用于同一主机多进程之间数据交互,分为传统管道、System V IPC、Socket 网络通信。
- 无名管道 pipe :仅支持亲缘进程(父子);内核缓冲区 FIFO;
pipe()创建,read/write 读写。 - 有名管道 FIFO (mkfifo):本机任意进程通信,以文件形式存在。
- 信号 :异步软中断通知,不携带业务数据;
signal()注册信号处理函数。
✨小结
- 文件编程分清标准 IO(库、带缓冲)、文件 IO(系统调用 fd,操作硬件);
- 进程资源独立,开销大;线程共享进程资源,开销小,但是会带来资源竞争;
- fork 产生子进程要注意僵尸进程回收;多线程访问公共资源必须使用互斥锁 / 信号量,警惕死锁;
- 进程不能直接访问对方内存,必须依靠 IPC 机制完成通信。