我正在使用gRPC进行C App(gRPC Server)和Java App(gRPC Client)之间的进程间通信 . 一切都在一台机器上运行 . 我想提供客户端关闭服务器的可能性 . 我的想法是在proto中添加RPC函数来进行服务 .
C实施将是:
class Service : public grpcGeneratedService
{
public:
......
private:
grpc::Server* m_pServer;
};
grpc::Status Service::ShutDown(grpc::ServerContext* pContext, const ShutDownRequest* pRequest, ShutDownResponse* pResponse)
{
if (m_pServer)
m_pServer->Shutdown();
return grpc::Status(grpc::StatusCode::OK, "");
}
然而,ShutDown阻塞,直到所有RPC调用都被处理,这意味着死锁 . 有没有优雅的方法如何实现它?
2 回答
我正在使用std :: promise,其方法几乎和你的一样 .
为了使这项工作,我在第二个线程中调用
server->Wait()
并等待将来的exit_requested
承诺阻止关闭调用:一旦我有了这个,我也能够通过信号处理程序支持干净关机:
到目前为止,我对这种方法感到满意,并且它使我保持在gRPC和标准c libs的范围内 . 而不是使用一些全局作用的承诺(我必须在服务实现源中将其声明为外部)我应该想到更优雅的东西 .
这里需要注意的一点是,多次设置promise的值会引发异常 . 如果您以某种方式发送关闭消息并同时发送
pkill -2 my_awesome_service
,则可能会发生这种情况 . 当我的持久层中出现死锁以防止关闭完成时,我实际上遇到了这种情况,当我尝试再次发送SIGINT时,服务中止了!对于我的需求,这仍然是一个可接受的解决方案,但我很想知道解决这个小问题的替代方案 .您可以从ShutDown()处理程序创建一个std :: function,并在单独的线程(或线程池)中运行该函数 . 这将允许将RPC的处理与关闭逻辑的执行分离,并消除死锁 .