课程介绍
以超过百万行源代码的大型C语言项目为目标,本训练营将通过真实案例引领大家理解困扰这类项目的棘手问题,并且给出解决问题的最佳实践。通过4大主题,探讨的范围模块之间依赖混乱,包括为了支持不同硬件、产品SKU而导致的代码重复,内存使用不当,以及线程管理、内核同步等方面的问题。
课程对象
从事大型C语言项目的软件开发工程师、测试工程师、项目带头人和技术经理
课程形式
讲解 + 真实案例演示 + 讲师引领的动手试验
主题A:模块划分和团队间依赖
第一部分:样板项目之Windows 2000(1.5小时)
总代码行数:1亿行,项目背景,开发团队规模,测试团队规模,代码行数,项目管理工具,瑕疵数据,子项目划分,目录结构,设计文档,团队文化,成功经验:显式依赖,子项目间独立,并行开发
第二部分:样板项目之Linux内核(1.5小时)
总代码行数:大于2500万行,参与人数,协作方式,逻辑架构和核心组件,目录结构,命名习惯,与用户空间接口(外部接口),内部接口,static与EXPORT_SYMBOL
第三部分:显式依赖(1.5小时)
依赖的必然性,显式(explicit)依赖和隐式(implicit)依赖,函数依赖,数据结构依赖,头文件组织,内部头文件和外部头文件,C语言的封装技巧,代码实例
第四部分:二进制兼容(1.5小时)
源代码兼容和二进制兼容,Linux内核的策略,函数级别的CRC校验,Linux应用程序的策略,真实试验,成功案例,影响二进制兼容的典型原因,导入和导出,plt,代码实例
主题B:产品演进和代码重复
第一部分:样板项目之X GPU驱动(1.5小时)
GPU概要,GPU驱动之功能,驱动模型,OS接口,OS演进,硬件接口,硬件演进,平台抽象,功能抽象,函数重复
第二部分:样板项目之i915驱动(1.5小时)
Linux下的图形栈,DRM,i915和i915驱动,文件组织,功能抽象,底层接口封装,处理硬件差异,区别对待,电源管理和频率控制代码分析
第三部分:样板项目之Linux文件系统(1.5小时)
VFS概要,VFS架构,伪文件系统,四大类对象和四大类操作,EXT2、EXT3和EXT4,函数指针表,理解C语言实现的继承和派生,内核对象,深刻理解文件抽象,C语言之面向对象
第四部分:功能抽象和代码合并(1.5小时)
对象和操作,i915中的成功案例,操作符和操作数,操作符和操作数的关系,对操作数的依赖,泛型编程,Alex Stepanov,STL中的泛型编程技术
主题C:内存误用
第一部分:认识Glibc堆(1.5小时)
用户态堆,ptmalloc,arena,heap,主arena的布局,辅arena的创建,堆块结构,分配策略,bin,bin的组织,分配过程,释放过程,堆有关的错误
第二部分:样板项目之GTK(1.5小时)
GIMP Toolkit,GUI框架,调整,用法示例,源代码结构,分配内存,显式分配和隐式分配,分配模式,观察工具
第三部分:内存错误检查工具(1.5小时)
Valgrind,valgind的工作原理,影子内存,Address Sanitizer(ASan),ASan的工作原理,影子记录,检查过程,额外开销
第四部分:高效使用内存(1.5小时)
页错误,Major fault和Minor fault,物理内存组织,大内存页,页表缓存(TLB),内存对齐,cache结构,cache miss,数据结构,局部性,代码局部性和数据局部性,使用VTune优化内存访问,案例演示
主题D:多线程和同步
第一部分:样板项目之DPDK(1.5小时)
源于INTEL,DPDK简要历史,版本,协议,DPDK的架构,设计思想,核心组件,驱动层,KNI模块,用户空间的库,包处理过程,线程模型,绑定CPU,Run-to-completion,流水线, 配置流水线,流水线实例解析,包转发,负载均衡,流水线结构的可视化
第二部分:LINUX系统的任务管理(1.5小时)
进程和线程,LWP,任务结构体,一体二用,进程属性,线程结构体,内核态栈,寻找内核态栈的方法,内核态栈溢出;调度队列,观察队列长度,线程优先级,线程调度器,线程局部存储,特殊的gs段
第三部分:线程模型(1.5小时)
按需创建,线程池,异常退出,监护方法,信号和信号处理,线程和堆的关联,创建线程的开销,频繁创建的负作用
第四部分:线程同步(1.5小时)
同步的必要性,多线程安全的访问,内核对象,条件变量,互斥量,事件,CPU的同步机制,互锁系列指令,无锁设计,全局锁,锁的粒度,多线程死锁,使用GDB调试死锁问题,使用VTune分析多线程的同步问题,使用KernelShark观察线程的唤醒时间