在eos源码目录中programs/nodeos/main.cpp文件里,为节点启动的主函数
main函数内部做了两件事
1 初始化 application

  1. if(!app().initialize<chain_plugin, http_plugin, net_plugin, producer_plugin>(argc, argv))
  2. return INITIALIZE_FAIL;

2 application启动和插件启动

  1. app().startup();
  2. 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展开

展开后

  1. void plugin_requires( Lambda&& l ) {
  2. l(appbase::app().register_plugin<net_plugin>())
  3. l(appbase::app().register_plugin<http_plugin>())
  4. }

就是采用注册的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、函数,内部展开如下:

  1. static_cast<net_plugin*>(this)->plugin_requires([&](auto& plug){ plug.initialize(options); });
  2. static_cast<net_plugin*>(this)->plugin_initialize(options);
  3. static_cast<net_plugin*>(this)->plugin_startup();
  4. static_cast<net_plugin*>(this)->plugin_shutdown();

APPBASE_PLUGIN_REQUIRES((chain_plugin))展开

  1. void plugin_requires( Lambda&& l ) {
  2. l(appbase::app().register_plugin<chain_plugin>()
  3. }

所以static_cast<net_plugin*>(this)->plugin_requires(&{ plug.initialize(options); });
实际继续展开内部调用appbase::app().register_plugin<chain_plugin>().initialize(options);完成网络部分的初始化。
startup,shutdown也是一样的道理。

谢谢关注我的公众号

eos节点启动源码分析的更多相关文章

  1. RocketMQ中Broker的启动源码分析(一)

    在RocketMQ中,使用BrokerStartup作为启动类,相较于NameServer的启动,Broker作为RocketMQ的核心可复杂得多 [RocketMQ中NameServer的启动源码分 ...

  2. RocketMQ中Broker的启动源码分析(二)

    接着上一篇博客  [RocketMQ中Broker的启动源码分析(一)] 在完成准备工作后,调用start方法: public static BrokerController start(Broker ...

  3. RocketMQ中PullConsumer的启动源码分析

    通过DefaultMQPullConsumer作为默认实现,这里的启动过程和Producer很相似,但相比复杂一些 [RocketMQ中Producer的启动源码分析] DefaultMQPullCo ...

  4. Django如何启动源码分析

    Django如何启动源码分析 启动 我们启动Django是通过python manage.py runsever的命令 解决 这句话就是执行manage.py文件,并在命令行发送一个runsever字 ...

  5. Netty源码分析 (三)----- 服务端启动源码分析

    本文接着前两篇文章来讲,主要讲服务端类剩下的部分,我们还是来先看看服务端的代码 /** * Created by chenhao on 2019/9/4. */ public final class ...

  6. 【Netty之旅四】你一定看得懂的Netty客户端启动源码分析!

    前言 前面小飞已经讲解了NIO和Netty服务端启动,这一讲是Client的启动过程. 源码系列的文章依旧还是遵循大白话+画图的风格来讲解,本文Netty源码及以后的文章版本都基于:4.1.22.Fi ...

  7. Quartz源码——scheduler.start()启动源码分析(二)

    scheduler.start()是Quartz的启动方式!下面进行分析,方便自己查看! 我都是分析的jobStore 方式为jdbc的SimpleTrigger!RAM的方式类似分析方式! Quar ...

  8. Seata AT 模式启动源码分析

    从上一篇文章「分布式事务中间件Seata的设计原理」讲了下 Seata AT 模式的一些设计原理,从中也知道了 AT 模式的三个角色(RM.TM.TC),接下来我会更新 Seata 源码分析系列文章. ...

  9. Netty服务端的启动源码分析

    ServerBootstrap的构造: public class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, Serve ...

随机推荐

  1. Luogu P1120 小木棍 [数据加强版]

    看了题目心中只有一个字——搜索!!! 但是很显然,朴素的搜索(回溯)绝壁超时. 剪枝&优化(要搞很多,要不然过不了) 1:从小到大搜索它们的因数,这样找到就exit. 2:将数据从大到小排序, ...

  2. centos7 部署 nginx+tomcat+MariaDB 环境并安装安全狗,使用natapp隧道

    jdk安装: -openjdk 参考:https://blog.csdn.net/dhr201499/article/details/81626466 tomcat安装: 使用版本:8.5.37 参考 ...

  3. windows下如何查看进程、端口占用、杀死进程教程

    一. 查看所有进程占用的端口 在开始-运行-cmd,输入:netstat –ano 可以查看所有进程 二.查看占用指定端口的程序 当你在用tomcat发布程序时,经常会遇到端口被占用的情况,我们想知道 ...

  4. 真机调试傻瓜图文教程(Xcode6.4)

    先准备好99刀,真机调试才带你玩. PS:万能宝十来块钱可以买个资格... Developer Apple上的设置 1.打开https://developer.apple.com/,点击Member ...

  5. NAND Flash底层原理,SLC MLC TLC比较

    NAND-Flash 的存储原理 固态硬盘最小单元的基本架构如下: 我们知道计算机中所有的信息储存最终都必须回归到 0与1,原则上,只要存储单元能提供两种或两种以上可供辨识的状态,便可以拿来纪录数据. ...

  6. torchvision 批量可视化图片

    1.1 简介 计算机视觉中,我们需要观察我们的神经网络输出是否合理.因此就需要进行可视化的操作. orchvision是独立于pytorch的关于图像操作的一些方便工具库. torchvision的详 ...

  7. 比较 VGG, resnet和inception的图像分类效果

    简介 VGG, resnet和inception是3种典型的卷积神经网络结构. VGG采用了3*3的卷积核,逐步扩大通道数量 resnet中,每两层卷积增加一个旁路 inception实现了卷积核的并 ...

  8. 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 ...

  9. Spring学习总结之面向切面(AOP)

    AOP术语 通知(advice):定义切面是什么以及什么时候使用 连接点(join point):应用在执行过程中能够插入切面的点 切点(pointcut):切点的定义会匹配通知所要织入的一个或多个连 ...

  10. opencv2 用imwrite 抽取并保存视频图像帧

    最近在写一个车辆检测程序,程序中需要获取图像帧,并保存为图片,且放到指定目录中去,我在网上查了很多发现都是opencv1的有关操作,没有opencv2的操作,我参考网上的例子,结合着用opencv2新 ...