[gRPC] 关闭异步服务器

[gRPC] 关闭异步服务器

在grpc的异步模式下,如何正确的关闭grpc服务呢?

一般来讲,我们使用异步模式时grpc会写一个主循环,轮询所有请求

void* tag;
bool ok;
while (likely(!(*force_quit))) {	// 参见代码规范中的中断处理
    cq.Next(&tag, &ok);	// 参考官网教程中的写法
    if (ok) {
        switch(tag) {	// 判断收到的是哪个请求
                ...
        }
    }
    else
        break;
}

那怎么中断这个循环呢?

  1. *force_quit=true,没用。因为cq.Next阻塞中,并不会返回。

  2. 参考gRPC: What is the recommended way to shut down an asynchronous server in C++? - Stack Overflow,需要分别执行cq.Shutdown()server.Shutdown,但我试了一下,还是会阻塞在cq.Next里。

    (无论cq和server哪个先Shutdown,最后都会阻塞住)

  3. 放弃使用cq.Next,改为使用cq.AsyncNext(&tag, &ok, deadline)。deadline是一个时间限制,超过时限后这个函数就会返回。这样就不用担心cq.Next永远阻塞的问题了。

改进后的写法:

void* tag;
bool ok;
gpr_timespec deadline;
deadline.clock_type = GPR_TIMESPAN;
deadline.tv_sec = 1;
deadline.tv_nsec = 0;

while (likely(!(*force_quit))) {	// 参见代码规范中的中断处理
    switch(cq.AsyncNext(&tag, &ok, deadline)) {
    	case ServerCompletionQueue::NextStatus::GOT_EVENT:
            if (ok) {
                switch(tag) {	// 判断收到的是哪个请求
                        ...
                }
            }
        default:
            break;
    }
}
posted @ 2022-11-10 21:49  CQzhangyu  阅读(291)  评论(0编辑  收藏  举报