怎么理解一个规模大且结构复杂的c工程源码
很久以前,当要着手一个规模很大,结构复杂的c工程源码时,总是感觉无从下手。这个时候,一般google一下”XX源码分析“。当这个源码是很广泛使用的时,这样到也能得到不少启发;很不幸,经常要接触一些很少人使用的源码所以慢慢也就总结了一些规律和步骤。
1.0 了解项目的用途、基本原理、主要组件. 这些信息一般在开源项目的主页都有,了解里面用到的基本理论(比如memcache的LRU, epoll, zookeeper用到的paxos原理等),同时看看主要的组成部分;一般大半天看完;
1.1 有些项目源码的readme或doc里面有源码的框架介绍、主要技术、术语规范等,看代码前应该先了解;(例如haproxy的doc里面就有架构说明,主要模块的结构图)
1.2 只要有条件,初步运行起来,用最简单的方式(例如官方手册中推荐的配置或者example),体验一下。认真看一下每个命令行参数,也很有帮助。
2. 看main函数。main函数包含了初始化以及总的运行架构。一般所有用到的东西都在初始化有体现,整个程序的执行框架也会在main函数体现得很清晰。只要粗略看一下流程,这时肯定不少是不明白的;
3. 看头文件的数据结构。c毕竟还是以数据为中心的流程控制语言,了解数据的组织方式是非常关键的。我一般是遍历所有头文件,寻找主要的数据结构,并在纸上画出他们的主要关联图。同时,对于一些重要的状态标志位信息(一般为一串宏定义),弄懂它的关系。ps:头文件的注释很有用,大部分开源项目在头文件说明这个数据结构的用途、各字段的意义、为什么这么设计、优缺点等。
4. 跟读主流程。一般为用户触发的处理流程。以memcache为例,以command process的过程为主线,很容易就理解整个框架了;
5. 跟读各种事件通知、消息、信号量处理过程。一般都在main函数的loop中。除了用户触发的处理流程,大部分代码都在处理这些工作,同时它们也是非常重要的,也是最容易出现bug的地方;
6. 通读所有代码。这里的“通读”,是指查看所有的文件,看看除了主流程和事件消息处理外,还有没有其他重要的代码被遗漏。
7. 对于一些通用功能,只要知道主要的接口用途就可以了,没有必要研究它的实现(有兴趣有时间除外),例如hash、各种树处理、log、各种位图运算、各种事件poll机制、各种链表实现、各种第三方lib和插件。。等等,他们一般都是用独立文件存放的,只看接口说明就足够了;
8. 如果代码实在太复杂,各种钩子函数级联,建议运行起来,用gdb break一个最基本的函数(例如访问最小数据单元的函数),然后看看调用栈,根据调用关系查看往往事半功倍;
完成上面几步,基本上就了然于心了。下一步可以添加或修改一些小功能,进一步了解细节;对于实现复杂的核心代码,反复多看即便,就可以进行更深入的工作了。
怎么理解一个规模大且结构复杂的c工程源码的更多相关文章
- 大数据学习笔记——HDFS写入过程源码分析(2)
HDFS写入过程注释解读 & 源码分析 此篇博客承接上一篇未讲完的内容,将会着重分析一下在Namenode获取到元数据后,具体是如何向datanode节点写入真实的数据的 1. 框架图展示 在 ...
- 大数据学习笔记——HDFS写入过程源码分析(1)
HDFS写入过程方法调用逻辑 & 源码注释解读 前一篇介绍HDFS模块的博客中,我们重点从实践角度介绍了各种API如何使用以及IDEA的基本安装和配置步骤,而从这一篇开始,将会正式整理HDFS ...
- Maven 使用了一个标准的目录结构和一个默认的构建生命周期。
Maven 使用了一个标准的目录结构和一个默认的构建生命周期. 约定优于配置 当创建 Maven 工程时,Maven 会创建默认的工程结构.开发者只需要合理的放置文件,而在 pom.xml 中不再需要 ...
- 转自一个CG大神的文章
<如何学好游戏3D引擎编程>此篇文章献给那些为了游戏编程不怕困难的热血青年,它的神秘要我永远不间断的去挑战自我,超越自我,这样才能攀登到游戏技术的最高峰 ——阿哲VS自 ...
- 文件加载---理解一个project的第一步
当我最开始写php的时候,总是担心这个问题:我在这儿new的一个class能加载到对应的类文件吗?毕竟一运行就报Fatal Error,什么**文件没找到,类无法实例化等等是一种很“低级”的错误,怕别 ...
- Leetcode 496. 下一个更大元素 I
1.题目描述 给定两个没有重复元素的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集.找到 nums1 中每个元素在 nums2 中的下一个比其大的值. nums1 中数字 ...
- LeetCode:下一个更大元素I【31】
LeetCode:下一个更大元素I[31] 题目描述 给定两个没有重复元素的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集.找到 nums1 中每个元素在 nums2 中的 ...
- Druid:一个用于大数据实时处理的开源分布式系统
Druid是一个用于大数据实时查询和分析的高容错.高性能开源分布式系统,旨在快速处理大规模的数据,并能够实现快速查询和分析.尤其是当发生代码部署.机器故障以及其他产品系统遇到宕机等情况时,Druid仍 ...
- Leetcode---栈系列刷题(python3实现)----#496 下一个更大元素I
给定两个没有重复元素的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集.找到 nums1 中每个元素在 nums2 中的下一个比其大的值. nums1 中数字 x 的下一个更 ...
随机推荐
- CF1151F Sonya and Informatics
cf luogu 我们最终要的序列一定是前面全是0,后面全是1,假设总共\(m\)个0,那么这等价于前\(m\)位0的个数为\(m\).当然一开始可能数量没有\(m\) 那就把前\(m\)位0的数量作 ...
- CSS-百分百布局
1.照片随着大小变化: 这里面重点就是每个包裹盒子是25%,图片是100%显示: <div class="box2"> <p> //这里都是4个: < ...
- Vue路由守卫之组件内路由守卫
beforeRouteEnter,进入路由前.需要注意这里不能使用this,因为我们使用的是进入路由之前,那会组件还没创建,得不到this这个属性,所有我们只能使用过vm异步语句来让 ...
- 多线程编程-- part 5.2 JUC锁之Condition条件
1.Condition介绍 Condition的作用是对锁进行更精确的控制.Condition中的await()方法相当于Object的wait()方法,Condition中的signal()方法相当 ...
- centos7搭建activemq服务
一.下载安装jdk 下载 jdk-8u211-linux-x64.rpm安装: yum -y install jdk-8u211-linux-x64.rpm 二.官网下载 activemq 软件包 官 ...
- 2019-2020-1 20199319《Linux内核原理与分析》第八周作业
可执行程序工作原理 ELF目标文件格式 1.目标文件(ABI,应用程序二进制接口):编译器生成的文件. 2.目标文件的格式:out格式.COFF格式.PE(windows)格式.ELF(Linux)格 ...
- RPM包搭建
打包rpm软件包之spec文件解析 1. 概述 RPM的全称是(Red Hat Package Manager,Red Hat包管理器).RPM是一个开放的软件包管理器,工作在Red Hat.类Lin ...
- redis3.2 源码安装
wget http://download.redis.io/releases/redis-3.2.3.tar.gz tar -zxvf redis-.tar.gz cd redis make & ...
- mysql在某一字段后面添加新字段
mysql在某一字段后面添加新字段 ALTER TABLE `test` ADD `anyField` TEXT NOT NULL AFTER `id`
- java8学习之流的短路与并发流
并发流: 从api的角度来看,其实跟咱们之前一直在用的stream()方式差不多,但是底层是有明显的不同,所以这里初步先对并发流有一个基本的认识, 说到串行与并行,最直观的感受就是效率的不同,所以下面 ...