很久以前,当要着手一个规模很大,结构复杂的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. 原生javascript的意义

    原生JS是指遵循ECMAscript标准的javascript,不同于微软的jscript也不依赖于任何框架,依托于浏览器标准引擎的脚本语言. jquery是在原生态的js上集成的框架资源,使用jqu ...

  2. VS2017 VS2019 无法进入安装界面闪退问题(windows7SP1)

    如果离线安装 Visual Studio 2017/2019出现“即将完成…一切即将准备就绪.”的画面后,等几秒安装程序没有任何错误提示就关闭了,无法继续安装. 解决方法: 将vs_enterpris ...

  3. QQ恶搞 - 让艾特你的人语无伦次

    效果图: 实现过程: 代码: ‮ 将上面的代码复制添加到你的群名片后面即可. 原理解析: 这个代码是一个Unicode控制字符 - RLO,它可以控制在它后面的所有文本都已倒序的方式显示.在qq群艾特 ...

  4. Linux排查磁盘空间顺序解决空间不足问题

    1 先查看整个磁盘的情况 df    -h                     查看整台服务器的硬盘使用情况 cd    /                       进入根目录 du   -s ...

  5. kvm虚拟机热迁移

    一.热迁移描述: 相比KVM虚拟机冷迁移中需要拷贝虚拟机虚拟磁盘文件,kvm虚拟机热迁移无需拷贝虚拟磁盘文件,但是需要迁移到的宿主机之间需要有相同的目录结构虚拟机磁盘文件,也就是共享存储,本文这部分内 ...

  6. maven 学习之路之二(1)

    上次我简单讲了maven的安装和构建生命周期. 这一篇博客我将用实际项目来分享下maven整个构建生命周期的具体使用: 这次我将用maven做一个自己写程序的一个模版程序. 自己实现一个简单的页面登录 ...

  7. (转)linux特殊文件名字删除不了怎么办

    1. 文件名含有特殊字符,直接使用 rm 可能删除不了,可以使用如下方法: 1) 使用 ls -i 查处该文件的 inode 号,假设为654321 2) 使用find命令删除 find ./ -in ...

  8. mysql细说show slave status参数详解(最全)

    1. Slave_IO_State 这里显示了当前slave I/O线程的状态(slave连接到master的状态).状态信息和使用show processlist | grep "syst ...

  9. 【每日一包0008】arr-diff

    [github地址:https://github.com/ABCDdouyae...] arr-diff 多个数组比较,过滤出第一个数组独有的内容 用法:arr-diff(arr1, arr2, ar ...

  10. ${filename}用法一:${file内部的#%的匹配方式}

    假设我们定义了一个变量为: file=/dir1/dir2/dir3/my.file.txt 我们可以用${ }分别替换获得不同的值: ${file#*/}:拿掉第一条/及其左边的字串:dir1/di ...