C++ 学习项目 Linux任务调度系统

TaskScheduler 是一个Linux 环境下的高性能任务调度系统,支持资源管理、任务队列、超时控制、eBPF 性能分析和 Prometheus 监控。

核心功能

  • ✅ 多线程任务调度(生产者-消费者模型)
  • ✅ CPU/内存资源配额管理(线程安全)
  • ✅ 优先级队列 + FIFO 双模式
  • ✅ 进程生命周期管理(fork/exec、进程组、信号)
  • ✅ 优雅终止(SIGTERM → 宽限期 → SIGKILL)
  • ✅ eBPF 性能分析(bpftrace + 火焰图)
  • ✅ Prometheus 指标导出
  • ✅ 黑白名单安全控制
  • ✅ PSI 背压监控

这个项目涵盖的知识将直接应用于:

  • 云原生基础设施(Kubernetes调度器)
  • 大数据平台(YARN、Mesos)
  • 高性能计算(作业调度系统)
  • 性能工程(eBPF profiling、火焰图分析)

环境要求

组件 版本要求 检查命令
Linux内核 5.4+(eBPF需要) uname -r
GCC/G++ 11+ g++ --version
CMake 3.14+ cmake --version
bpftrace 0.11+(可选) bpftrace --version

TaskScheduler 7天学习计划汇总表

一、7天学习计划总览

天数 模块名称 核心功能 新增代码文件 关键技术点 可运行演示内容
第1天 基础设施 日志系统、项目框架 logger.h/cpp
main.cpp
CMakeLists.txt
CMake构建、单例模式、线程安全、时间格式化 输出带时间戳的三条日志
第2天 任务定义与资源管理 Job结构体、资源配额管理 job.h
resource_manager.h/cpp
scheduler_test.cpp
enum class、std::optional、互斥锁、GoogleTest 单元测试通过,资源预留/释放验证
第3天 调度器核心 任务队列、调度循环、指标收集 metrics.h/cpp
scheduler.h/cpp
原子操作、条件变量、生产者-消费者模型 多任务提交、队列等待、指标输出
第4天 进程启动与Cgroup fork/exec、进程组、资源限制 cgroup_helper.h/cpp
ebpf_profiler.h/cpp
进程创建、进程组、rlimit、空实现模式 真正执行echols命令
第5天 任务回收与超时控制 进程回收、超时检测、优雅终止 更新scheduler.cpp waitpid、僵尸进程、SIGTERM/SIGKILL、宽限期 超时任务被SIGTERM/SIGKILL终止
第6天 安全与监控 黑白名单、优先级、PSI背压、完整指标 更新metrics.h/cpp
更新scheduler.h/cpp
字符串解析、PSI文件读取、Prometheus格式 命令过滤、优先级调度、背压演示
第7天 eBPF性能分析 bpftrace集成、符号解析、火焰图 ebpf_profiler.cpp完整版
bpf/profile_task.bt
workload_*.cpp
eBPF、bpftrace、addr2line、c++filt 生成性能报告和火焰图SVG

二、每日学习内容详细表

第1天:基础设施

类别 内容
技术点 CMake构建、单例模式、RAII、线程安全、时间格式化
核心代码 Logger::instance()单例、std::scoped_lock自动加锁、std::chrono时间处理
重点概念 静态局部变量线程安全、localtime_r vs localtime#pragma once
运行验证 ./scheduler 输出3条带时间戳的日志
面试题 静态局部变量为什么线程安全?RAII是什么?system_clock vs steady_clock

第2天:任务定义与资源管理

类别 内容
技术点 enum class、std::optional、默认成员初始化、互斥锁、GoogleTest
核心代码 JobSpec/Job结构体、ResourceManager::reserve()原子操作、TEST
重点概念 强类型枚举、聚合初始化、check-then-act模式、结构化绑定
运行验证 ./tests/scheduler_tests 2个测试全部通过
面试题 enum class vs enumstd::optional使用场景?析构函数应该抛异常吗?

第3天:调度器核心

类别 内容
技术点 std::atomic、内存序、条件变量、生产者-消费者模型、快照模式
核心代码 Metrics::add_queue_wait() CAS更新最大值、dispatcher_loop()调度循环、pick_next_job()优先级选择
重点概念 relaxed内存序、伪唤醒、资源预留失败重试
运行验证 提交3个任务,看到队列等待和指标输出
面试题 memory_order_relaxed含义?为什么需要条件变量?如何避免伪唤醒?

第4天:进程启动与Cgroup

类别 内容
技术点 fork/exec、写时复制、进程组、rlimit、空实现模式
核心代码 launch_job() fork+exec、setpgid(0,0)创建进程组、setrlimit()资源限制
重点概念 僵尸进程、孤儿进程、信号、SIGSTOP/SIGCONT
运行验证 ./scheduler --cmd "echo hello" 看到命令输出
面试题 fork() vs vfork()?写时复制如何实现?进程组作用?

第5天:任务回收与超时控制

类别 内容
技术点 waitpid、退出状态解析、两阶段终止、宽限期管理
核心代码 reaper_loop()非阻塞回收、kill(-pgid, SIGTERM)WIFEXITED/WIFSIGNALED
重点概念 僵尸进程避免、优雅终止、超时 vs 普通失败区分
运行验证 ./scheduler --cmd "sleep 10" --timeout 3 3秒后被终止
面试题 SIGTERM vs SIGKILL?WNOHANG作用?如何判断进程被信号杀死?

第6天:安全与监控

类别 内容
技术点 字符串解析、PSI压力监控、Prometheus指标格式、背压控制
核心代码 黑白名单检查、read_pressure_avg10()解析PSI、to_prometheus()指标导出
重点概念 默认拒绝安全模型、系统压力阈值、Counter vs Gauge
运行验证 白名单拒绝cat命令、优先级调度、背压日志
面试题 白名单 vs 黑名单?PSI是什么?如何用于负载感知调度?

第7天:eBPF性能分析

类别 内容
技术点 eBPF/bpftrace、探针类型、符号解析、火焰图生成
核心代码 profile_task.bt脚本、resolve_symbols() addr2line集成、generate_flamegraphs() SVG生成
重点概念 on-CPU vs off-CPU分析、用户态栈回溯、DWARF调试信息
运行验证 sudo ./scheduler --cmd "./workload_cpu" --enable-ebpf 生成火焰图
面试题 eBPF vs 内核模块?如何获取用户态调用栈?off-CPU分析重要性?

三、你能学到什么?

3.1 C++核心技术

技术类别 具体知识点 在项目中的应用
C++11/14/17/20 自动类型推导(auto)、范围for、lambda表达式 遍历容器、谓词函数
右值引用、移动语义 std::move(opts)std::unique_ptr
变参模板 GoogleTest的EXPECT_*
结构化绑定(C++17) auto [cpu, mem] = used()
if constexpr(C++17) 编译期条件判断
std::optional(C++17) end_time可选值
并发编程 std::thread dispatcher、reaper、psi三个线程
std::mutex / std::scoped_lock 保护pending_running_
std::condition_variable 生产者-消费者同步
std::atomic 指标计数器、shutting_down_标志
内存序(memory_order) relaxed用于计数器
RAII与智能指针 std::unique_ptr profilers_映射管理
std::lock_guard / scoped_lock 自动加锁解锁
构造函数/析构函数 资源获取与释放
设计模式 单例模式(Singleton) Logger::instance()
工厂模式 Job对象创建
观察者模式 Metrics收集指标
策略模式 优先级调度策略

3.2 Linux系统编程

技术类别 具体知识点 在项目中的应用
进程管理 fork() 创建子进程执行任务
exec族函数 替换进程映像执行命令
waitpid() 回收子进程,防止僵尸
进程组(setpgid) 统一管理任务的所有子进程
信号处理 SIGTERM/SIGKILL 优雅终止超时任务
SIGSTOP/SIGCONT 暂停/恢复进程用于eBPF追踪
raise() 子进程暂停自己
资源限制 setrlimit() 限制文件描述符、禁用core dump
getrlimit() 获取当前限制
文件系统 chdir() 切换工作目录
/proc文件系统 读取进程maps、内存信息
cgroup v2 cpu.max / memory.max 限制CPU和内存(第7天)
cgroup.procs 将进程加入cgroup
memory.pressure / cpu.pressure PSI压力监控

3.3 性能分析工具

工具/技术 用途 在项目中的应用
eBPF/bpftrace 动态内核追踪 CPU采样、系统调用追踪、off-CPU分析
addr2line 地址转函数名 解析用户态调用栈
c++filt C++符号反修饰 还原可读的函数名
perf 性能采样 替代方案(未直接使用)
FlameGraph 火焰图生成 可视化性能瓶颈
Prometheus 指标导出 暴露/metrics端点

3.4 构建与测试

技术 用途
CMake 跨平台构建、依赖管理
FetchContent 自动下载GoogleTest
GoogleTest 单元测试框架
address sanitizer 内存错误检测(可选)

alt

alt

alt

alt

4.3 线程模型

线程名称 职责 同步机制 与主线程关系
主线程 接收任务提交、解析命令行 互斥锁 创建其他线程
dispatcher 从队列取任务、启动子进程 条件变量 + 互斥锁 独立运行
reaper 回收子进程、超时检测 互斥锁 独立运行
psi_monitor 读取PSI文件、更新背压标志 原子变量 可选,cgroup启用时运行

五、技术栈总结表

层次 技术 用途
语言 C++17/C++20 主开发语言
构建 CMake 3.14+ 跨平台构建
测试 GoogleTest 单元测试
并发 std::thread, std::mutex, std::atomic, std::condition_variable 多线程调度
进程 fork, exec, waitpid, kill, setpgid 进程管理
信号 SIGTERM, SIGKILL, SIGSTOP, SIGCONT, SIGCHLD 进程控制
资源 setrlimit, cgroup v2 资源限制
监控 PSI (pressure stall information) 系统压力监控
性能 eBPF, bpftrace, addr2line, c++filt 性能分析
可视化 FlameGraph (flamegraph.pl) 火焰图生成
指标 Prometheus文本格式 指标导出
日志 自定义Logger 运行时日志

六、学习成果验证表

天数 验证命令 预期结果
第1天 ./scheduler 输出3条带时间戳的日志
第2天 ./tests/scheduler_tests 2个测试全部PASSED
第3天 ./scheduler 提交3个任务,看到队列等待和指标输出
第4天 ./scheduler --cmd "echo hello" 输出 "hello"
第5天 ./scheduler --cmd "sleep 10" --timeout 3 3秒后任务被终止
第6天 ./scheduler --cmd "cat /etc/passwd" --whitelist "echo,ls" 任务被拒绝(不在白名单)
第7天 sudo ./scheduler --cmd "./workload_cpu" --enable-ebpf 生成taskscheduler_ebpf/*.svg火焰图

部分技术点展示:

一、C++语言特性

1.1 枚举类(enum class)

enum class JobStatus {
    Pending, Running, Succeeded, Failed, Timeout, Cancelled
};
特性 传统enum enum class
作用域 全局作用域 强作用域(需JobStatus::Pending
隐式转换 可转int 不可隐式转换
底层类型 不固定 可指定(如: uint8_t
类型安全

1.2 std::optional

std::optional<std::chrono::steady_clock::time_point> end_time{};

// 检查是否有值
if (job.end_time.has_value()) {
    auto t = job.end_time.value();
}

// 或使用指针风格
if (auto& t = job.end_time) {
    // t 是有效引用
}

使用场景:表示"可能有值,也可能没有"的状态,避免使用特殊值(如-1)或额外bool标志。

1.3 默认成员初始化

struct JobSpec {
    std::string cmd;
    int cpu_cores{1};        // C++11起支持
    size_t memory_mb{256};
};

// 使用
JobSpec spec{"ls"};  // cpu_cores=1, memory_mb=256

1.4 结构化绑定(C++17)

// 返回pair
std::pair<int, size_t> used() const;

// 解包
auto [cpu, mem] = rm.used();  // cpu = int, mem = size_t

1.5 RAII与智能指针

// std::unique_ptr - 独占所有权
std::unique_ptr<EbpfProfiler> profiler = std::make_unique<EbpfProfiler>();
profilers_.emplace(job.id, std::move(profiler));  // 转移所有权

// 自动析构:离开作用域自动delete

RAII核心原则:资源获取即初始化,析构函数自动释放资源。

部分面试题展示

一、C++语言基础题(10题)

Q1:enum class 和传统 enum 有什么区别?

参考答案

特性 传统enum enum class
作用域 全局作用域(容易冲突) 强作用域(需JobStatus::Pending
隐式转换 可隐式转换为int 不可隐式转换,需static_cast
底层类型 不固定,编译器决定 可指定(如: uint8_t
类型安全
// 传统enum - 有问题
enum Color { Red, Green, Blue };
enum Status { Red, Yellow, Green };  // 编译错误!Red/Green重复

// enum class - 正确
enum class Color { Red, Green, Blue };
enum class Status { Red, Yellow, Green };  // OK

Q2:std::optional 是什么?什么时候用?

参考答案std::optional 表示"可能有值,也可能没有值",用于替代特殊值模式(如用-1表示不存在)。

本项目应用

std::optional<std::chrono::steady_clock::time_point> end_time{};
// 任务运行时没有end_time,结束后才有

对比传统方式

// 传统方式 - 需要额外标志
time_point end_time;
bool has_end_time;  // 容易忘记维护

// 现代方式 - 自文档化
std::optional<time_point> end_time;
if (end_time.has_value()) { ... }

Q3:std::unique_ptrstd::shared_ptr 的区别?

参考答案

特性 unique_ptr shared_ptr
所有权 独占 共享(引用计数)
拷贝 不可拷贝,可移动 可拷贝
开销 零开销 引用计数开销
使用场景 明确唯一所有者 多个对象共享

本项目应用

std::unordered_map<int, std::unique_ptr<EbpfProfiler>> profilers_;
// 每个任务只有一个profiler,用unique_ptr

Q4:什么是RAII?本项目哪里用到了?

参考答案: RAII(Resource Acquisition Is Initialization)是将资源生命周期与对象生命周期绑定的编程范式。

本项目应用

  1. 互斥锁std::scoped_lock lk(mu_),离开作用域自动解锁
  2. 智能指针std::unique_ptr自动释放内存
  3. 文件流std::ifstream离开作用域自动关闭文件
void log(const std::string& msg) {
    std::scoped_lock lk(mu_);  // 构造时加锁
    std::cout << msg << std::endl;
    // 析构时自动解锁,即使抛异常也会解锁
}

部分简历展示

模板1:C++后端开发工程师

个人信息

张三 | 185-XXXX-XXXX | ********** | GitHub: github.com/zhangsan

教育背景

  • XX大学 | 计算机科学与技术 | 本科

专业技能

  • 熟练掌握C++11/14/17/20,理解RAII、智能指针、移动语义等现代C++特性
  • 熟悉Linux环境下的多线程编程,掌握互斥锁、条件变量、原子操作等同步机制
  • 熟悉进程管理、信号处理、IPC通信等Linux系统编程
  • 掌握CMake构建系统,GoogleTest单元测试框架

项目经验

TaskScheduler - 高性能任务调度系统 | C++ | 2025.03 - 2025.04

项目描述:开发了一个Linux环境下的多线程任务调度器,支持资源管理、任务队列、超时控制和性能分析。

技术栈:C++17/20、pthread、Linux系统调用、eBPF、Prometheus

核心职责

  • 设计并实现了线程安全的资源管理器(ResourceManager),支持CPU/内存配额的动态预留和释放
  • 实现基于条件变量的生产者-消费者调度模型,支持优先级队列和任务排队机制
  • 开发进程回收模块(Reaper),通过waitpid非阻塞回收子进程,实现超时任务的SIGTERM→SIGKILL优雅终止
  • 集成eBPF/bpftrace性能分析器,通过addr2line和c++filt实现符号解析,自动生成On-CPU/Off-CPU火焰图
  • 实现Prometheus格式的指标导出,包含任务计数、排队延迟、PSI背压等20+监控指标

项目成果

  • 支持同时管理1000+任务队列,任务调度延迟平均<1ms
  • 通过eBPF分析定位IO瓶颈,优化fsync调用,性能提升30%
#简历中的项目经历要怎么写#
全部评论

相关推荐

05-19 16:41
复旦大学 Python
ynq2126:我一直觉得现在考算法题没啥意义 真要选拔人才不如把公司实际项目中遇到的问题当成一系列场景题抛给求职者答 这才是能检测能力的东西
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务