[gRPC] 關閉異步服務器
在grpc的異步模式下,如何正確的關閉grpc服務呢?
一般來講,我們使用異步模式時grpc會寫一個主循環,輪詢所有請求
void* tag;
bool ok;
while (likely(!(*force_quit))) { // 參見代碼規範中的中斷處理
cq.Next(&tag, &ok); // 參考官網教程中的寫法
if (ok) {
switch(tag) { // 判斷收到的是哪個請求
...
}
}
else
break;
}
那怎麼中斷這個循環呢?
-
設
*force_quit=true
,沒用。因爲cq.Next
阻塞中,並不會返回。 -
參考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,最後都會阻塞住)
-
放棄使用
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;
}
}