很久以前,当要着手一个规模很大,结构复杂的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工程源码的更多相关文章

  1. 大数据学习笔记——HDFS写入过程源码分析(2)

    HDFS写入过程注释解读 & 源码分析 此篇博客承接上一篇未讲完的内容,将会着重分析一下在Namenode获取到元数据后,具体是如何向datanode节点写入真实的数据的 1. 框架图展示 在 ...

  2. 大数据学习笔记——HDFS写入过程源码分析(1)

    HDFS写入过程方法调用逻辑 & 源码注释解读 前一篇介绍HDFS模块的博客中,我们重点从实践角度介绍了各种API如何使用以及IDEA的基本安装和配置步骤,而从这一篇开始,将会正式整理HDFS ...

  3. Maven 使用了一个标准的目录结构和一个默认的构建生命周期。

    Maven 使用了一个标准的目录结构和一个默认的构建生命周期. 约定优于配置 当创建 Maven 工程时,Maven 会创建默认的工程结构.开发者只需要合理的放置文件,而在 pom.xml 中不再需要 ...

  4. 转自一个CG大神的文章

    <如何学好游戏3D引擎编程>此篇文章献给那些为了游戏编程不怕困难的热血青年,它的神秘要我永远不间断的去挑战自我,超越自我,这样才能攀登到游戏技术的最高峰           ——阿哲VS自 ...

  5. 文件加载---理解一个project的第一步

    当我最开始写php的时候,总是担心这个问题:我在这儿new的一个class能加载到对应的类文件吗?毕竟一运行就报Fatal Error,什么**文件没找到,类无法实例化等等是一种很“低级”的错误,怕别 ...

  6. Leetcode 496. 下一个更大元素 I

    1.题目描述 给定两个没有重复元素的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集.找到 nums1 中每个元素在 nums2 中的下一个比其大的值. nums1 中数字  ...

  7. LeetCode:下一个更大元素I【31】

    LeetCode:下一个更大元素I[31] 题目描述 给定两个没有重复元素的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集.找到 nums1 中每个元素在 nums2 中的 ...

  8. Druid:一个用于大数据实时处理的开源分布式系统

    Druid是一个用于大数据实时查询和分析的高容错.高性能开源分布式系统,旨在快速处理大规模的数据,并能够实现快速查询和分析.尤其是当发生代码部署.机器故障以及其他产品系统遇到宕机等情况时,Druid仍 ...

  9. Leetcode---栈系列刷题(python3实现)----#496 下一个更大元素I

    给定两个没有重复元素的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集.找到 nums1 中每个元素在 nums2 中的下一个比其大的值. nums1 中数字 x 的下一个更 ...

随机推荐

  1. JDBC2

    1.JDBC连接池 public class JdbcTemplateDemo2 { //Junit单元测试,可以让方法独立执行 //1. 获取JDBCTemplate对象 private JdbcT ...

  2. 关于hdfs的一些认知

    先从网上copy一些优势点 1.高容错性数据自动保存多个副本.它通过增加副本的形式,提高容错性.某一个副本丢失以后,它可以自动恢复,这是由 HDFS 内部机制实现的,我们不必关心. 2.适合批处理它是 ...

  3. CDH5.16.1的Yarn提交任务默认资源分配

    1 同时运行5个Spark任务的资源分配截图 2 每个任务占用3个Container 3个core以及4.5GB内存 也就是说一个Container需要 1个core 以及 512MB的内存 如果资源 ...

  4. iperf和iperf3详解

    一.iperf server端: iperf -s -p 25001 -B 192.168.33.103 (-u) -s  指定server端 -p 指定端口(要和客户端一致) -B 绑定ip地址 - ...

  5. 解压速度更快, Zstandard 1.4.1 发布

    zstd 1.4.1 发布了,zstd 又叫 Zstandard,它是一种快速无损压缩算法,主要应用于 zlib 级别的实时压缩场景,并且具有更好的压缩比.zstd 还可以以压缩速度为代价提供更强的压 ...

  6. python动态添加属性

    class A: def __init__(self, info ={}): self.info = info def __getattr__(self, item): return self.inf ...

  7. 七,ingress及ingress cluster

    目录 Service 类型 namespace 名称空间 Ingress Controller Ingress Ingress-nginx 进行测试 创建对应的后端Pod和Service 创建 Ing ...

  8. python将str类型的数据变成datetime时间类型数据

    如下: import datetime date_str = '2019_05_09' date_date = datetime.date(*map(int, date_str.split('_')) ...

  9. Rinetd 通过ECS端口转发到内网RDS

    前置条件 实现目的:开发本地电脑需要连接没有外网地址的RDS,通过ECS进行转发连接到RDS数据库 客户 PC 终端可以 ssh 登录有公网的 ECS 服务器. 有公网的 ECS 服务器可以通过内网访 ...

  10. 模拟赛小结:2017 China Collegiate Programming Contest Final (CCPC-Final 2017)

    比赛链接:传送门 前期大顺风,2:30金区中游.后期开题乏力,掉到银尾.4:59绝杀I,但罚时太高卡在银首. Problem A - Dogs and Cages 00:09:45 (+) Solve ...