php小編西瓜認為,"由 time.AfterFunc() 遞歸調用的 goroutine 的設計很糟糕"這句話反映了一種不合理的設計思路。在並發程式設計中,遞歸呼叫的 goroutine 可能導致資源消耗過大,甚至引發死鎖和記憶體溢位等問題。因此,應該謹慎使用遞歸調用,並考慮使用其他替代方案來解決問題,以確保程式的效能和穩定性。在編寫程式碼時,我們應該時時注意設計的合理性,避免出現不必要的問題。
我有一個小型 http 應用程式 (A)。在啟動時,它會呼叫另一個 http 服務 (B) 來驗證許可證,如果許可證正常,則 http 伺服器 (A) 啟動。如果驗證失敗A則出現致命錯誤退出
許可證檢查每 24 小時進行一次
每 24 小時遞歸創建一個新的 goroutine 會被認為是一個糟糕的設計嗎?檢查下面我的程式碼。之前的goroutine會關閉還是繼續運行然後n個goroutine互相調用而結束
每個新的 goroutine 是從主 goroutine 調用還是從子 goroutine 調用?
func Request(retry bool) error { // request and verify license (external http service) err := verify_license() if err != nil { return err } if retry { // Renew verification timeout (renew license every 24 hours) time.AfterFunc(LICENSE_TIMEOUT, func(){ request_retry() }) } return nil } func request_retry(){ for i := 0; i < LICENSE_RETRY; i++ { if err := v.Request(false); err == nil { break } time.Sleep(LICENSE_RETRY_TIMEOUT) } time.Sleep(LICENSE_TIMEOUT) v.Request(true) }
if err := license_verify.Request(true); err != nil { log.Fatal(err.Error()) }
也許你可以重新思考問題的設計。例如:
func main() { if !checkLicense() { log.Fatal("license check failed") } srv := http.Server{} // ctx, cancel := context.WithCancel(context.Background()) defer cancel() go func() { for { select { case <-ctx.Done(): // in case you want to instal signal handlers etc return case <-time.After(24 * time.Hour): if !checkLicense() { cancel() // or srv.Shtdown, really depends on you } } } }() if err := srv.ListenAndServe(); err != nil { log.Fatal(err) } } func checkLicense() bool { // add retries per request here }
基本上,它的作用是創建一個 goroutine,定期檢查並在出現問題時通知上下文或通道。
如果我正確理解了這個問題,那麼你只需要保持簡單。一個建置區塊是請求失敗時重試。除此之外,是 24 小時重試。最後一層是,如果檢查失敗,則對其做出反應。您可以使用上下文、頻道或您真正喜歡的任何內容
以上是由 time.AfterFunc() 遞歸呼叫的 goroutine 的設計很糟糕的詳細內容。更多資訊請關注PHP中文網其他相關文章!