很久以前,当要着手一个规模很大,结构复杂的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. java实现spark常用算子之map

    import org.apache.spark.SparkConf;import org.apache.spark.api.java.JavaRDD;import org.apache.spark.a ...

  2. 帝国cms 描述和关键词动态获取

    之前列表页首页和内容页调用的关键词和描述的字段不一样,所以说需要写好几套模板. 下边这个判断就不用像之前做几套模板了,通过判断获取不一样的字段. $GLOBALS[navinfor] 这个判断的是此页 ...

  3. 计算机网络:这是一份全面 & 详细 的TCP协议学习指南

    原文链接:blog.csdn.net 用这个媒体播放器组件,实时互动时也可共同观看本地视频juejin.im 前言 计算机网络基础 该是程序猿需掌握的知识,但往往会被忽略 今天,我将详细讲解计算机网络 ...

  4. react 基础语法使用

    刚开始不久react,在菜鸟上及其他前辈网站上学习,下面开始我的自学笔记. 包括: 渲染元素 组件(函数方法定义.es6 class定义) 事件处理 条件渲染 列表 下面代码部分将不会再写html部分 ...

  5. Django的MySQL Driver配置

    PEP 249规定了Python的数据库API.MySQL主要有三种API实现: MySQLdb 是Andy Dustman开发的.使用原生代码/C语言绑定的驱动,它已经开发了数十年. mysqlcl ...

  6. 修改MySQL表中自增编号

    alter table 表名 AUTO_INCREMENT = 值 例:

  7. linux版宝塔安装Redis

    1安装服务 2配置设置 3安装PHP扩展 首先,我们来安装服务,进入管理面板--软件管理--运行环境--redis-点击安装,等待完成 完成之后开始第二步,配置设置.这一步根据自己需要进行配置.注意安 ...

  8. php页面加载完毕后再显示购买按钮

    php页面加载完毕后再显示购买按钮 $document.ready(function(){ $("#buybotton").show()})

  9. java8 lambda表达式应用

    1.用lambda表达式实现Runnable非常简单// Java 8之前: new Thread(new Runnable() { @Override public void run() { Sys ...

  10. Django学习系列13:Django ORM和第一个模型

    ORM—对象关系映射器,是一个数据抽象层,描述存储在数据库中的表,行和列.处理数据库时,可以使用熟悉的面向对象方式,写出更好的代码. 在ORM的概念中,类对应数据库中的表,属性对应列,类的单个实例表示 ...