lspling 是一套面向 Linux 系统编程的动手练习集,按 Robert Love 的
Linux System Programming(第 2 版)逐章、逐知识点编排。
每个练习都是一个可以独立编译和运行的 C 程序。初始文件故意保留 TODO
或错误的实现;你需要修改代码,让编译和测试通过。练习覆盖从
errno、文件描述符、缓冲 I/O,到进程、线程、信号、时间以及 GCC 扩展
的全部路径。
- 140 个练习,12 个章节:对应原书第 1 章到第 11 章和附录 A。
- 自带测试框架:不依赖 Catch2、GoogleTest 或第三方库。
- 自带 CLI:列出、运行、提示、查看答案、重置进度和监听文件变化。
- 严格的编译反馈:默认使用
-Wall -Wextra -Wpedantic -Werror -Wshadow -Wformat=2, 让你习惯阅读编译器诊断。 - 答案与初始模板分离:
solutions/保存参考答案,templates/保存原始练习,exercises/是你实际修改的目录。 - 练习规格驱动:
tools/specs_*.py是唯一的练习事实来源, 参考实现和初始练习由生成器同步。 - 有据可依:每个练习都标注了它对应的书名小节和页码, 映射见 docs/curriculum.md 与 docs/knowledge-map.md。
- Linux(练习直接调用 Linux/POSIX 接口,如
epoll、inotify、mremap、sched_*) - C 编译器:GCC 或 Clang(C17,POSIX 线程)
- Python 3.8+(运行
./lsplingCLI) - GNU Make(可选)
- CMake 3.20+(可选)
Debian/Ubuntu 上通常只需要:
sudo apt install build-essential python3# 查看全部练习
./lspling list
# 按章节查看
./lspling list --topic 01_file_io
# 运行下一个未完成的练习
./lspling run
# 运行指定练习(支持完整 ID、目录名或唯一后缀)
./lspling run 04_read_all
./lspling run 01_file_io/04_read_all
# 查看目标、章节出处和提示
./lspling hint 04_read_all
# 查看参考答案
./lspling solution 04_read_all
# 直接应用答案(会覆盖你的练习文件)
./lspling solution 04_read_all --apply
# 恢复初始练习
./lspling reset 04_read_all
# 监听文件变化,保存后自动重跑
./lspling watch 04_read_all也可以使用 Makefile:
make list
make run
make verify
make selftest
make doctor
make clean- 打开书本对应章节,阅读练习目录下的
exercises/<章节>/README.md。 - 按练习文件顶部的
objective、reference、hint修改代码。 - 运行
./lspling run <exercise>,根据编译器诊断或测试输出迭代。 - 卡住时先
./lspling hint <exercise>,再看答案。 - 通过后进度记录在
.lspling/progress.json。 - 完成一章后,对照 docs/knowledge-map.md 检查是否理解相关系统调用。
- 最后运行
./lspling verify验证全部参考答案,或./lspling selftest检查项目自身的完整性。
练习的初始状态是刻意坏掉的:有的编译失败,有的能编译但测试失败。 这也是练习目标之一——学会根据编译器诊断和测试输出定位问题。
| 章节 | 主题 | 书本页码 | 练习数 |
|---|---|---|---|
| 1 | 00_introduction 系统编程基础、errno、文件与进程概念 |
1-24 | 10 |
| 2 | 01_file_io 文件描述符、open/read/write/lseek、select/poll |
25-66 | 13 |
| 3 | 02_buffered_io 用户缓冲、标准 I/O、流锁 |
67-90 | 14 |
| 4 | 03_advanced_file_io readv/writev、epoll、mmap、fadvise |
91-136 | 11 |
| 5 | 04_process_management fork/exec/wait、用户与组、会话 |
137-176 | 12 |
| 6 | 05_advanced_processes 调度、nice、亲和性、资源限制 |
177-210 | 9 |
| 7 | 06_threading pthread、互斥量、条件变量、取消 |
211-240 | 10 |
| 8 | 07_files_directories stat/chmod/xattr、目录、链接、inotify |
241-292 | 13 |
| 9 | 08_memory_management 地址空间、malloc、brk、mmap、mlock |
293-332 | 12 |
| 10 | 09_signals 信号处理、信号集、sigsuspend、sigqueue |
333-362 | 12 |
| 11 | 10_time 时间类型、POSIX 时钟、睡眠、定时器 |
363-394 | 12 |
| A | 11_gcc_extensions typeof、属性、case 区间、指针算术 |
395-406 | 12 |
总计 140 个练习。完整映射见 docs/curriculum.md。
.
├── lspling # 零依赖 Python CLI
├── exercises/ # 你要修改的练习
│ ├── 00_introduction/
│ ├── ...
│ └── 11_gcc_extensions/
├── solutions/ # 参考答案(与 exercises 同结构)
├── templates/ # 原始练习,用于 ./lspling reset
├── include/lspling/test.h # 自带测试框架
├── tools/
│ ├── generate_exercises.py # 从规格生成练习/答案/模板/文档
│ ├── spec.py # 练习规格数据结构
│ ├── specs_ch01.py ... # 每章练习规格
│ └── specs_appendix_a.py
├── docs/
│ ├── architecture.md # 运行器、生成器、测试框架设计
│ ├── curriculum.md # 按章节列出全部练习(生成)
│ └── knowledge-map.md # 按知识领域列出覆盖范围
├── .ref/ # 参考书与提取文本(被 .gitignore 忽略)
├── CMakeLists.txt
├── CMakePresets.json
├── Makefile
└── Dockerfile
./lspling 会在需要时用系统编译器编译单个练习,构建产物放在
build/lspling/。
./lspling doctor
./lspling verify
./lspling selftestmake verify
make selftest
make check-generatedcmake --preset default
cmake --build --preset default
ctest --preset defaultCMake 默认只构建 solutions/ 中的答案,并把它们注册为 CTest 测试。
初始练习使用 EXCLUDE_FROM_ALL,避免故意失败的练习阻塞整个构建。
docker build -t lspling .
docker run --rm -it -v "$PWD:/lspling" lspling ./lspling list默认编译参数:
-std=c17 -Wall -Wextra -Wpedantic -Werror -Wshadow
-Wstrict-prototypes -Wpointer-arith -Wformat=2 -Wundef
-D_POSIX_C_SOURCE=200809L -D_DEFAULT_SOURCE -D_GNU_SOURCE -g -O0
_GNU_SOURCE 是刻意加上的:书中的 mremap()、mincore()、inotify、
malloc_usable_size()、sched_getcpu() 等 Linux 专有接口都需要它。
需要 GNU 语法(case 区间、语句表达式、void * 算术)的练习会在
文件内部用 #pragma GCC diagnostic 局部关闭对应的 pedantic 警告,
这本身也是这些练习要教的内容。
可以通过环境变量覆盖:
CC=clang ./lspling verify
CFLAGS="-fsanitize=address,undefined" ./lspling run 08_memory_management/02_malloc_and_free如果安装了 valgrind、clang-tidy 或 cppcheck,建议对内存、指针和
线程相关的章节额外运行:
valgrind ./build/lspling/08_memory_management/02_malloc_and_free.solution
clang-tidy exercises/08_memory_management/02_malloc_and_free.c -- -std=c17 -Iinclude -D_GNU_SOURCE练习由 tools/specs_*.py 中的规格生成。每个规格包含正确代码、测试代码
和一组“正确片段 -> 初始片段”的替换。这样练习和答案不会不同步。
# 编辑 tools/specs_ch02.py 之类的文件
python3 tools/generate_exercises.py
./lspling verify
./lspling selftest
python3 tools/generate_exercises.py --check注意:exercises/、solutions/、templates/ 和
docs/curriculum.md 都是生成产物,请改规格文件而不是改它们。
项目代码使用 MIT License,见 LICENSE。
- Robert Love, Linux System Programming, 2nd Edition, O'Reilly, 2013. (练习的章节划分、目标和页码引用都来自这本书)
clings:本项目的结构与 CLI 设计参照了同目录下的 C 语言练习集。- rustlings 及其衍生项目, 它们确立了“初始失败、答案通过、规格驱动”的练习集形态。
man手册:man 2 intro、man 7 signal、man 7 pthreads。