很久以前,当要着手一个规模很大,结构复杂的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. Linux scp命令详解(服务器之间复制文件或目录)

    scp:服务器之间复制文件或目录 一.命令格式: scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file] [-l limit] ...

  3. MySQL5.7修改数据库目录!

    MySQL5.7默认安装,修改之前,停止MySQL服务. 数据库目录:C:\ProgramData\MySQL\MySQL Server 5.7\Data 配置文件:C:\ProgramData\My ...

  4. Caffe中im2col的实现解析

    这里,我是将Caffe中im2col的解析过程直接拉了出来,使用C++进行了输出,方便理解.代码如下: #include<iostream> using namespace std; bo ...

  5. (转)Java并发编程:核心理论

    原文链接:https://www.cnblogs.com/paddix/p/5374810.html Java并发编程系列: Java 并发编程:核心理论 Java并发编程:Synchronized及 ...

  6. centos7搭建activemq服务

    一.下载安装jdk 下载 jdk-8u211-linux-x64.rpm安装: yum -y install jdk-8u211-linux-x64.rpm 二.官网下载 activemq 软件包 官 ...

  7. windows10 mysql主从复制配置

    注意:mysql主从复制,主从版本要一致! 生手永远在学习的路上,为了学习mysql主从复制,实现读写分离,于是在本地安装多个mysql实例来进行验证. 也因此有了下面的笔记,一来自我总结一下经验,二 ...

  8. Summer training round2 #3

    A!:                    GTY系列题 B!:莫队加分块  GTY系列题 C!:线段树模拟拓扑排序(把普通的拓扑排序的栈操作改成线段树区间减一,查询区间最右侧的0的位置即可.注意一 ...

  9. leetcode上题目的分类

    leetcode链表部分题目 https://zhuanlan.zhihu.com/p/29800285 <[Leetcode][链表]相关题目汇总/分析/总结> leetcode堆部分题 ...

  10. Java I/O(一)流和文件类File的概述、FileInputStream和FileInputStream

    一.流概述 & InputStream.OutputStream 流包括输入流和输出流,即I/O(Input和Output),具体结构如下: I/O类都被放在java.io包中,所有的输入流类 ...