前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >GRPC-C++源码分析(四)--ServerCompletionQueue

GRPC-C++源码分析(四)--ServerCompletionQueue

原创
作者头像
路小饭
修改2019-04-23 11:17:15
3.4K1
修改2019-04-23 11:17:15
举报

对应《GRPC-C++源码分析(三)--main线程》中的1.1节 初始化ServerCompletionQueue

1 overview

先来看下ServerCompletionQueue的整体结构

ServerCompletionQueue的核心在于创建了grpc_completion_queue* cq_,见其父类CompletionQueue的构造函数

代码语言:txt
复制
  CompletionQueue(const grpc_completion_queue_attributes& attributes) {
    cq_ = g_core_codegen_interface->grpc_completion_queue_create(
        g_core_codegen_interface->grpc_completion_queue_factory_lookup(
            &attributes),
        &attributes, NULL);
    InitialAvalanching();  // reserve this for the future shutdown
  }

而CompletionQueue则继承了GrpcLibraryCodegen。了解ServerCompletionQueue类需要我们从顶级父类一层层分析

2 GrpcLibraryCodegen

代码语言:txt
复制
class GrpcLibraryCodegen {
 public:
  GrpcLibraryCodegen(bool call_grpc_init = true) : grpc_init_called_(false) {
    if (call_grpc_init) {
      GPR_CODEGEN_ASSERT(g_glip &&
                         "gRPC library not initialized. See "
                         "grpc::internal::GrpcLibraryInitializer.");
      g_glip->init();
      grpc_init_called_ = true;
    }
  }

GrpcLibraryCodegen极为简单,仅仅调用了g_glip->init();所以重点在g_glip上,让我们看看它的来源

  • g_glip在GrpcLibraryInitializer类的构造函数中被初始化。
  • grpc声明了一个全局的静态变量static internal::GrpcLibraryInitializer g_gli_initializer;以确保在main函数之前就完成了g_glip的初始化
代码语言:txt
复制
class GrpcLibraryInitializer final {
 public:
  GrpcLibraryInitializer() {
    if (grpc::g_glip == nullptr) {
      static auto* const g_gli = new GrpcLibrary();
      grpc::g_glip = g_gli;
    }
    if (grpc::g_core_codegen_interface == nullptr) {
      static auto* const g_core_codegen = new CoreCodegen();
      grpc::g_core_codegen_interface = g_core_codegen;
    }
  }
  • 在代码中可以看到,除了g_glip 外,还有grpc::g_core_codegen_interface也初始化了。这个变量会被用在CompletionQueue的构造函数中,后面会说到
  • 从图中可以看到g_glip->init方法实际调用的是GrpcLibrary中的init方法
代码语言:txt
复制
class GrpcLibrary final : public GrpcLibraryInterface {
 public:
  void init() override { grpc_init(); }
  void shutdown() override { grpc_shutdown(); }
};
  • 重点转移到了grpc_init()方法中

2.1 grpc_init(init.cc)

顾名思义,grpc_init代表的是初始化grpc核心参数,所以在此方法中,可以看到n多*_init()方法,目前先把注意力放在grpc_iomgr_init();

  • 在grpc_iomgr_init中,开始涉及到grpc/src/core部分的代码,这是c风格的库。
  • 这里决定了后续使用的是哪个系统平台的reactor模型,epoll还是poll,或者其他
  • 还记得线程模型中的default-executor和resolver-executor么,它们是由grpc_core::Executor::InitAll方法启动的
  • grpc_iomgr_platform_init的最终作用是赋值给全局变量:static const grpc_event_engine_vtable* g_event_engine = nullptr;后面的分析会看到

2.1.1 grpc_core::Executor::InitAll

代码语言:javascript
复制
//executor.cc
void Executor::InitAll() {
  EXECUTOR_TRACE0("Executor::InitAll() enter");

  // Return if Executor::InitAll() is already called earlier
  if (executors[static_cast<size_t>(ExecutorType::DEFAULT)] != nullptr) {
    GPR_ASSERT(executors[static_cast<size_t>(ExecutorType::RESOLVER)] !=
               nullptr);
    return;
  }

  executors[static_cast<size_t>(ExecutorType::DEFAULT)] =
      grpc_core::New<Executor>("default-executor");
  executors[static_cast<size_t>(ExecutorType::RESOLVER)] =
      grpc_core::New<Executor>("resolver-executor");

  executors[static_cast<size_t>(ExecutorType::DEFAULT)]->Init();
  executors[static_cast<size_t>(ExecutorType::RESOLVER)]->Init();

  EXECUTOR_TRACE0("Executor::InitAll() done");
}
  • Init方法中启动的各自的线程,比较好跟踪,不再赘述

grpc_determine_iomgr_platform和grpc_iomgr_platform_init方法我们放在下一章统一说明

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 overview
  • 2 GrpcLibraryCodegen
    • 2.1 grpc_init(init.cc)
      • 2.1.1 grpc_core::Executor::InitAll
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档