[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;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章