eos节点启动源码分析
在eos源码目录中programs/nodeos/main.cpp文件里,为节点启动的主函数
main函数内部做了两件事
1 初始化 application
- if(!app().initialize<chain_plugin, http_plugin, net_plugin, producer_plugin>(argc, argv))
- return INITIALIZE_FAIL;
2 application启动和插件启动
- app().startup();
- app().exec();
application类
先说application的基本实现和常用接口,application 定义了注册插件的函数,获取插件,查找插件等功能,根据模板动态绑定的
同样定义了一些私有函数和变量
application 构造函数为私有的,方便实现单例模式,plugins为存储各类注册插件的map,key为插件名,value为独占的基类指针,不可copy。
io_serv为boost库提供的io_service的shared_ptr,网络通信和事件注册派发会用到。initialized_plugins为已经初始化的插件vector,
running_plugins为已经runing的插件vector。
erased_method_ptr和erased_channel_ptr分别在method.hpp和channel.hpp中实现了定义,以后用到再分析。
application类protected部分包含三个函数
initialize_impl 根据配置初始化插件。
plugin_initialized 将插件放入初始化vector
plugin_started 将插件放入runing vector
下面是application实现的单例模式,定义全局函数app(),内部调用application类静态函数instance()
application的start函数内部调用了各个插件的startup,出现异常shutdown
exec()内部注册了SIGINT,SIGTERM,SIGPIPE信号,当进程收到这几个信号会导致ioservice->stop(),否则io_ser->run()一直监听等待就绪事件
plugin类
abstract_plugin为所有插件继承的纯虚类,不同插件会实现各自特有的功能
plugin.hpp中定义了
BOOST_PP_SEQ_FOR_EACH为boost定义的宏,按照参数PLUGINS依次展开,将lambda函数l和每个PLUGIN传入
APPBASE_PLUGIN_REQUIRES_VISIT,比如net_api_plugin展开
展开后
- void plugin_requires( Lambda&& l ) {
- l(appbase::app().register_plugin<net_plugin>())
- l(appbase::app().register_plugin<http_plugin>())
- }
就是采用注册的lambda表达式依次调用,并且将各个插件注册到application中。
plugin 继承了abstract_plugin类
Impl是模板类型,不同的插件会传入不同的模板类型,initialize,startup,shutdown为虚函数,重写了基类abstract_plugin的功能。内部通过
static_cast<Impl*>(this)转化为对应的不同模板类型的plugin,进而实现特定功能的绑定,初始化,启动,停止等。举例:
net_plugin 继承了plugin,并且模板类型为net_plugin,这样当plugin<net_plugin>调用initialize、startup、shutdown、函数,内部展开如下:
- static_cast<net_plugin*>(this)->plugin_requires([&](auto& plug){ plug.initialize(options); });
- static_cast<net_plugin*>(this)->plugin_initialize(options);
- static_cast<net_plugin*>(this)->plugin_startup();
- static_cast<net_plugin*>(this)->plugin_shutdown();
APPBASE_PLUGIN_REQUIRES((chain_plugin))展开
- void plugin_requires( Lambda&& l ) {
- l(appbase::app().register_plugin<chain_plugin>()
- }
所以static_cast<net_plugin*>(this)->plugin_requires(&{ plug.initialize(options); });
实际继续展开内部调用appbase::app().register_plugin<chain_plugin>().initialize(options);完成网络部分的初始化。
startup,shutdown也是一样的道理。
谢谢关注我的公众号
eos节点启动源码分析的更多相关文章
- RocketMQ中Broker的启动源码分析(一)
在RocketMQ中,使用BrokerStartup作为启动类,相较于NameServer的启动,Broker作为RocketMQ的核心可复杂得多 [RocketMQ中NameServer的启动源码分 ...
- RocketMQ中Broker的启动源码分析(二)
接着上一篇博客 [RocketMQ中Broker的启动源码分析(一)] 在完成准备工作后,调用start方法: public static BrokerController start(Broker ...
- RocketMQ中PullConsumer的启动源码分析
通过DefaultMQPullConsumer作为默认实现,这里的启动过程和Producer很相似,但相比复杂一些 [RocketMQ中Producer的启动源码分析] DefaultMQPullCo ...
- Django如何启动源码分析
Django如何启动源码分析 启动 我们启动Django是通过python manage.py runsever的命令 解决 这句话就是执行manage.py文件,并在命令行发送一个runsever字 ...
- Netty源码分析 (三)----- 服务端启动源码分析
本文接着前两篇文章来讲,主要讲服务端类剩下的部分,我们还是来先看看服务端的代码 /** * Created by chenhao on 2019/9/4. */ public final class ...
- 【Netty之旅四】你一定看得懂的Netty客户端启动源码分析!
前言 前面小飞已经讲解了NIO和Netty服务端启动,这一讲是Client的启动过程. 源码系列的文章依旧还是遵循大白话+画图的风格来讲解,本文Netty源码及以后的文章版本都基于:4.1.22.Fi ...
- Quartz源码——scheduler.start()启动源码分析(二)
scheduler.start()是Quartz的启动方式!下面进行分析,方便自己查看! 我都是分析的jobStore 方式为jdbc的SimpleTrigger!RAM的方式类似分析方式! Quar ...
- Seata AT 模式启动源码分析
从上一篇文章「分布式事务中间件Seata的设计原理」讲了下 Seata AT 模式的一些设计原理,从中也知道了 AT 模式的三个角色(RM.TM.TC),接下来我会更新 Seata 源码分析系列文章. ...
- Netty服务端的启动源码分析
ServerBootstrap的构造: public class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, Serve ...
随机推荐
- Luogu P1120 小木棍 [数据加强版]
看了题目心中只有一个字——搜索!!! 但是很显然,朴素的搜索(回溯)绝壁超时. 剪枝&优化(要搞很多,要不然过不了) 1:从小到大搜索它们的因数,这样找到就exit. 2:将数据从大到小排序, ...
- centos7 部署 nginx+tomcat+MariaDB 环境并安装安全狗,使用natapp隧道
jdk安装: -openjdk 参考:https://blog.csdn.net/dhr201499/article/details/81626466 tomcat安装: 使用版本:8.5.37 参考 ...
- windows下如何查看进程、端口占用、杀死进程教程
一. 查看所有进程占用的端口 在开始-运行-cmd,输入:netstat –ano 可以查看所有进程 二.查看占用指定端口的程序 当你在用tomcat发布程序时,经常会遇到端口被占用的情况,我们想知道 ...
- 真机调试傻瓜图文教程(Xcode6.4)
先准备好99刀,真机调试才带你玩. PS:万能宝十来块钱可以买个资格... Developer Apple上的设置 1.打开https://developer.apple.com/,点击Member ...
- NAND Flash底层原理,SLC MLC TLC比较
NAND-Flash 的存储原理 固态硬盘最小单元的基本架构如下: 我们知道计算机中所有的信息储存最终都必须回归到 0与1,原则上,只要存储单元能提供两种或两种以上可供辨识的状态,便可以拿来纪录数据. ...
- torchvision 批量可视化图片
1.1 简介 计算机视觉中,我们需要观察我们的神经网络输出是否合理.因此就需要进行可视化的操作. orchvision是独立于pytorch的关于图像操作的一些方便工具库. torchvision的详 ...
- 比较 VGG, resnet和inception的图像分类效果
简介 VGG, resnet和inception是3种典型的卷积神经网络结构. VGG采用了3*3的卷积核,逐步扩大通道数量 resnet中,每两层卷积增加一个旁路 inception实现了卷积核的并 ...
- PAT甲题题解-1033. To Fill or Not to Fill (25)-模拟
模拟先说一下例子,最后为方便起见,在目的地安增加一个费用为0的加油站0 1 2 3 4 5 6 7 87.1 7.0 7.2 6.85 7.5 7.0 7.3 6.0 00 150 200 300 4 ...
- Spring学习总结之面向切面(AOP)
AOP术语 通知(advice):定义切面是什么以及什么时候使用 连接点(join point):应用在执行过程中能够插入切面的点 切点(pointcut):切点的定义会匹配通知所要织入的一个或多个连 ...
- opencv2 用imwrite 抽取并保存视频图像帧
最近在写一个车辆检测程序,程序中需要获取图像帧,并保存为图片,且放到指定目录中去,我在网上查了很多发现都是opencv1的有关操作,没有opencv2的操作,我参考网上的例子,结合着用opencv2新 ...