快速上手大型软件项目有妙招:理清进程、线程、队列及组件间通信
前言
对于刚入职的新员工,总会遇到一个头疼的问题,那就是如何快速上手公司的大型软件项目。要知道,一般公司里的软件项目都经过上十年的迭代,软件功能很多、架构也很复杂。这比阅读一般的开源项目难度更大,虽然很棘手,但也不要慌,还是有套路可循的。
现代大型软件的基本架构
不管是开源项目还是公司大型软件,基本组成主要可以分成四部分:
1 源代码
没什么可说的,C/C++/JAVA/Python 等各种语言的源代码。
2 依赖的库文件
C/C++ 依赖的静态库(.a)和动态库文件(.so),JAVA 依赖的 package 等。
3 配置文件
配置文件的格式一般为 json、yml、xml(现在用的比较少了),这些配置文件存在的意义是什么呢?如果能硬编码在代码里,谁也不乐意维护这些杂七杂八的文件。但是,配置文件能使软件更灵活,能适应不同的应用场景、硬件平台、操作系统,还有些用于 LLT 测试等。
这些配置文件一般都放在不同的目录下,需要搞明白不同的配置文件对哪个代码模块起作用。
4 构建系统
现在有的开源项目用 meson(一款基于 Python3 的构建系统),后端采用 ninja(谷歌的一款增量编译器)。而公司里的 C/C++ 项目采用 cmake/make 居多,你要对如何编写 CMakeLists.txt 有一定的了解。
一般开源项目里还有个文件夹 examples,里面是一些示例代码。而公司的项目里当然少不了 LLT 测试代码等。
大型软件项目的分析思路
1 物理部署
现代大型软件系统一般都在都是云上运行,分布式、有主备,能容灾。而软件运行最小的载体是 VM(虚拟机)上跑的 docker(容器),一个 docker 里可以跑多个进程。云上虚拟资源的管理由 OpenStack 负责,而 K8S 管理着容器的创建、删除、生命周期等事宜。
2 程序运行开始阶段
上面零零散散讲了很多,到这里我们才进入正题。
现代大型软件必然会使用多进程、多线程技术。不同进程的代码阅读方法是一样的,你只要知道不同进程的功能是什么即可。这里,我们来看一个具体的进程。
以 C/C++ 为例(JAVA 也是如此),程序的入口是 main 函数,也就是一个进程的入口。进入 main 函数执行的初期,一般是一些初始化、部署、加载等操作,比如读配置文件、加载程序运行所需要的 so、加载进程模版、线程模版、队列模板等。
3 进程、线程
main 函数所在的线程称之为主线程,随着代码往下执行,相继会创建出许多子线程,这些子线程可以由主线程创建,也可以由其他子线程创建,每个子线程里都是死循环执行某个或者某些任务。你需要走读代码,了解以下几点:
有哪些类型的子线程(也就是线程模版个数)?不同类型的线程执行什么样的任务(也就是线程功能)?每种类型的子线程创建了多少个?这些子线程的创建顺序及创建时间点?每个子线程挂载了哪些任务,这些任务是什么?以及这些任务的调度方式和调度权重是什么?子线程上的任务有模板吗?比如任务单元之类的
4 线程间通信、队列
一个进程中的不同线程一般来说是相互独立的,比如不同的业务线程。但有时候,线程间也是需要通信的,比如控制线程和业务线程,线程间通信有哪几种方式呢?简单一点的有共享内存,稍微复杂一点的就是通过消息队列实现线程间通信的。你需要明确以下几点:
哪些线程间需要通信?不同的线程在什么情况下需要通信?通信的目的又是什么?有哪些队列类型(也就是队列模板个数)?不同线程使用的队列个数有几个?线程从哪个队列里读消息?线程往哪个队列里写消息?
一般来说,某个线程会往其他线程的队列里发消息,而从自己独有的线程队列里读消息。
5 模块代码
模块代码大体可以分为两大类:控制模块和业务模块。
而业务模块代码又可以分为许多子模块,也可以看成一个个微服务。不同的业务模块代码有的跑在不同的线程上,有的同时跑在多个线程上,这种情况下对于模块中所使用到的一些全局变量就需要加锁处理。大量微服务的业务代码跑在业务线程上,这需要一个任务调度框架。这个任务调度框架有多种实现方式,有基于状态机的,也可以基于事件路由。什么是事件路由呢?
我们事先在配置文件中定义好一堆事件,每个事件下面对应一些微服务处理模块。事件执行上有一个默认的顺序,但也可以在得到某个特定的微服务执行结果时,跳转到非默认事件。
6 走读代码的利器 - 调试工具
上述列的问题需要我们走读代码才能寻找到答案。而使用 GDB(Linux 系统下 GNU 的调试工具)可以边调试边走读代码,gdb 可以清晰打印出函数调用栈(命令:bt)信息和线程信息(命令:info thread)。这里强烈推荐大家使用如下命令,跟踪某个具体线程上函数调用情况:
b 函数名(文件名:行号)thread 线程ID
总结
不管是 Windows、Linux 还是 Andorid 中的大型软件,上手方法都是大同小异的。从软件的部署、组成、进程、线程、组件、队列及线程间通信的角度入手,你将迅速对整个工程有了全面认识,而那些具体函数是怎么实现的,逐行看代码就行了,也是阅读大型软件程序中最为简单的部分了。
以上是个人的一些经验分享,希望对你有所帮助。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了