当前位置: 首页 > 知识库问答 >
问题:

在客户端上使用gRPC C,如何保持库的单线程?

史昊焱
2023-03-14

我需要将gRPC Cpp客户端库作为单个线程运行。据我所知,初始化grpc为执行器(默认执行器和解析器执行器)创建了两个线程,为计时器(从计时器管理器)创建了一到两个线程。我可以在创建后关闭这些线程,但我不知道如何防止它们被创建。有没有办法停止使用任何API创建它们?

假设我们有一个带有完成队列的cpp文件:

using grpc::CompletionQueue;

CompletionQueue* globalCompletionQueuePtr;

void main()
{
    globalCompletionQueuePtr = new CompletionQueue;
}

完成此操作后,我们将启动此序列:

  • 以这种方式创建CompletionQueue会初始化init中的grpc(grpc_init())。抄送
  • grpc_init将调用grpc_iomgr_init,然后调用grpc_core::Executor的InitAll关闭
  • 执行器中。ccInitAll创建默认和解析程序执行器,然后对每个执行器调用Init()
  • Init然后调用SetThreading(true),为每个执行器启动一个执行线程

现在我们有两个线程从主线程中分离出来,一个用于默认执行程序,一个用于解析器执行程序。不再深入研究这个问题,我可以通过调用grpc_corxecitor::SetThreadingAll(false);删除线程,但这意味着线程将创建并开始工作,然后被终止。

  1. 执行程序与轮询引擎有何关系?我看到执行程序运行闭包,但他们负责执行所有闭包吗?我可以在关闭闭包时运行闭包,因此我必须假设这发生在主线程上。对吗?
  2. 在上面的完成队列上调用AsyncNext会驱动队列上的操作按照留档所说的完成。我可以将操作推送到队列上(使用grpc_cq_begin_opgrpc_cq_end_op),我可以获取底层的污染集,创建一个污染,并使用它来自己安排调用。这样,看起来队列跟踪操作的状态,但它本身并不负责正在工作的操作。对吗?
  3. 我知道某些对grpc的调用需要grpc_core::ExecCtxexec_ctx;在堆栈上创建的上下文对象。堆栈ctx如何与解析器和默认执行器交互?是吗?
  4. 是否可以在没有执行器的情况下初始化grpc?调用SetThread(false)似乎可以保持库工作,但我不想创建线程然后杀死它们。

在iomgr初始化之后,与完成队列分离:

  • grpc_initininit.cc稍后调用grpc_iomgr_startiniomgr.cc调用grpc_timer_manager_initintimer_manager.cc
  • grpc_timer_manager_init做的最后一件事是调用start_threads()
  • start_threads()检查g_threaded以查看它需要启动一些线程,然后通过调用start_timer_thread_and_unlock

现在有一个计时器线程,它将计算下一个计时器启动的时间,睡眠到那个时间,然后醒来并启动计时器。如果线程用完,只要处于线程模式(g_threaded),我们就会启动另一个线程。代码基本上让我们处于线程模式,但有一个调用grpc\u timer\u manager\u set\u threading(false) timer_manager的code>将停止所有计时器线程。

  1. 对于这些计时器线程,相对于grpc调用,它们的主要用途是什么?计时器主要是内部构造还是公共API以某种方式使用它们?他们是否负责执行关闭的最后期限

最后,图书馆里还有什么其他东西可以让我看不见的线索出现吗?

我问所有这些问题的原因是,我需要在一个应用程序中运行grpc,该应用程序为库提供了一个运行线程。由于缺少线程而导致的性能下降不是一个问题。

如果我在这里说的任何话都不准确,请纠正我。我知道我对grpc cpp图书馆的理解还不完善。

提前感谢您的回答,感谢所有花时间阅读并提供支持的人。非常感谢!

我有一个特定的硬件环境,运行gRPC客户端的实际应用程序将管理多个线程。每个线程将获得一个要运行的时间片,并且必须在该时间片结束时完成。虽然额外的线程可以在该线程的时间片期间启动,但它们必须在该时间片结束时全部完成,以便下一个线程在给定其时间片时拥有所有可用的硬件资源。


共有1个答案

邢乐
2023-03-14

GRPC不支持单线程。至少,我们使用线程来运行计时器和解析器,以及您已经注意到的一些其他任务。

您可以通过使用异步服务器API而不是同步来避免线程膨胀,同步会为每个RPC创建一个新线程

但没有什么是单线程的

 类似资料:
  • 我尝试为我的网站提供文件上传/下载服务,并且尝试使用openstack中的对象存储。问题是,我通过php和openstack PHPSDK做这件事没有问题,但是当我试图通过一些javascript做这件事时,我找不到一个好的sdk或方法。我没有使用node,我有一个php服务器和一个javascript客户端。我想直接从javascript客户端上传或下载文件。我不希望文件通过php服务器传输。我

  • 有什么特殊的配置需要保持TwilioiOS客户端在后台活动吗?我已经启用了“VoIP”和“音频”权限,但是我注意到我的应用在后台大约10分钟后就退出了。请注意,我已经禁用了“TCDevice”播放的声音,并且还对AVAudio会话配置进行了一些更改。

  • 是否有办法限制netty用于客户端连接的线程数(netty是连接到远程服务器的客户端)。我使用的是1个NioEventLoopGroup,它被传递到每个引导程序中。每个引导都得到相同的通道初始值设定项引用(我曾经为每个引导创建不同的初始值设定项,但共享相同的引用似乎效果很好)。我从Java应用程序连接到许多充当服务器的硬件设备。 我注意到,目前最多使用16个线程(我在一台8核机器上,据我所知,Ne

  • 问题内容: 我想在客户端JavaScript应用程序中使用CommonJS模块系统。我选择nodejs作为实现,但是找不到有关如何使用nodejs客户端的任何教程或文档,即不使用 我在HTML页面中包含了像这样的node.js: 请注意,我没有在本地计算机上创建nodejs,无论如何我都在Windows上(我知道Cygwin选项)。当我想在自己的JavaScript中使用该函数时,它说它是未定义的

  • 我如何保护我的javascript客户端,你能推荐一些库吗。 提前谢谢你

  • 通常情况下,如果java webserver希望为多个请求提供服务(Jetty,...),服务器必须为每个请求打开一个线程。并且如果您有大量的请求,您必须将线程放入池中,以保持服务器工作而不死。 所以一些较新版本的Jetty支持异步Servlet,允许服务器保存所有请求的信息,而不需要线程等待事件将响应发回给客户端。您可以在此链接中找到 我有一些代码行: 函数获取客户端的请求信息并立即完成。事件将