gRPC:在 C++ 中关闭异步服务器的推荐方法是啥?
Posted
技术标签:
【中文标题】gRPC:在 C++ 中关闭异步服务器的推荐方法是啥?【英文标题】:gRPC: What is the recommended way to shut down an asynchronous server in C++?gRPC:在 C++ 中关闭异步服务器的推荐方法是什么? 【发布时间】:2016-06-13 00:16:23 【问题描述】:我有一个托管两个异步服务(“Master”和“Worker”)的 gRPC 服务器,我想为服务器实现正常关闭。每个服务都有自己的grpc::CompletionQueue
。
似乎有两个 Shutdown()
方法可能相关:grpc::CompletionQueue::Shutdown()
和 grpc::Server::Shutdown()
,但从文档中不清楚应该使用哪些方法。
什么是关闭异步服务的好模式?
【问题讨论】:
【参考方案1】: 等待() void grpc::Server::Wait () 覆盖虚拟 阻塞直到服务器关闭。警告 服务器必须正在关闭,或者某个其他线程必须调用 Shutdown 才能让此函数返回。
grpc::服务器关闭()http://static.grumpycoder.net/pixel/ref/c++/html/classgrpc_1_1_server.html
【讨论】:
【参考方案2】:TL;DR:您必须同时调用grpc::Server::Shutdown()
和grpc::CompletionQueue::Shutdown()
(对于服务中使用的每个完成队列)才能彻底关闭。
-
1234563从阅读相应 C API 方法 (
grpc_completion_queue_shutdown()
) 的文档来看,将新工作添加到队列中似乎是非法的——即通过调用RequestFoo()
——所以我在我的服务包装类(受互斥体保护)中添加了一个is_shutdown_
成员,这样在调用cq_->Shutdown()
之后就不会进行入队尝试。然而,在这样做之后,完成队列在cq_->Next()
中无限期地阻塞。所有入队的标签都不完整(有错误或其他原因)。
如果您改为调用 server_->Shutdown()
,则所有排队的标签都会立即完成(使用 ok == false
)。但是,完成队列在cq_->Next()
中继续无限期阻塞。
同时调用 cq_->Shutdown()
(对于每个定义的完成队列)和 server_->Shutdown()
会导致完全关闭。
一个警告:如果您使用grpc::ServerContext::AsyncNotifyWhenDone()
注册一个用于取消呼叫的标签,如果服务器在收到该呼叫的初始请求之前关闭,cq_->Next()
将不会返回这些标签.如果要避免内存泄漏,则需要谨慎处理相应标记结构的内存管理。
【讨论】:
伟大的自我回答!一些笔记。首先:根据the tutorial,服务器必须在完成队列(或多个队列)之前关闭。 第二:AsyncNotifyWhenDone()
没有被cq_->Next()
返回的事实可能是the docs for Next()
的意思,当它神秘地说“AsyncNotifyWhenDone: ok 应该始终为真”时。它还说对于客户端完成,因此可能在关闭期间也不会返回其标签。以上是关于gRPC:在 C++ 中关闭异步服务器的推荐方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章