我需要對每個請求應用一些測試,并根據測試結果進行響應。如果其中一項測試失敗,我需要立即發送響應,否則我會在所有測試成功完成后等待。我想用并發來做那個測試?,F在,我這樣做(簡化):func handler_request_checker(w http.ResponseWriter, r *http.Request) { done := make(chan bool) quit := make(chan bool) counter := 0 go TestOne(r,done,quit) go TestTwo(r,done,quit) .............. go TestTen(r,done,quit) for { select { case <- quit: fmt.Println("got quit signal") return case <- done: counter++ if counter == 10 { fmt.Println("All checks passed succesfully") return } } }func main() { http.HandleFunc("/", handler_request_checker) http.ListenAndServe()}goroutine 之一的示例:func TestOne(r *http.Request, done,quit chan bool) { ip,_,ok := net.SplitHostPort(r.RemoteAddr) if ok == nil { for _,item := range BAD_IP_LIST { if strings.Contains(ip,item) { quit <- true return } } done <- true return } else { quit <- true return }}問題是 goroutines 在我沒有退出信號后不會釋放內存。我想這是因為在完成的香奈兒里有一些東西。我是 GO 新手,所以也許我用錯了方法?例如,當我開始 load check 時http_load -parallel 10 -seconds 10,該 goroutine 很容易吃掉 100+ MB 的 RAM,并且不會將其返還給系統。在下一次檢查時,它會多吃 100+ MB,依此類推。如果我在沒有go(逐步)的情況下進行測試,則程序在進行任何負載檢查時不會超過 10-15mb
1 回答

嚕嚕噠
TA貢獻1784條經驗 獲得超7個贊
你的猜測是對的。您正在使用同步通道,這意味著發送方和接收方都必須可用才能傳輸值。
一旦您的handler_request_checker
函數收到退出信號,它就會停止檢索done
和quit
通道的任何值。此外TestOne
,TestTwo
當他們嘗試發送結果時,goroutines 將被阻止。更糟糕的是,它們將永遠留在內存中,因為它們仍在運行,因為它們尚未傳輸結果。
解決該問題的一個方法是使用緩沖(異步)通道done
和quit
。例如:
done := make(chan bool, 10) quit := make(chan bool, 10)
如果您在 10 個測試中使用大小為 10 的緩沖區,那么所有 goroutine 都能夠發送它們的結果,即使不再有可用的讀取器。所有 goroutine 將干凈地退出,并且一旦所有 goroutine 退出,通道(可能包含一些未讀結果)將被垃圾收集。
- 1 回答
- 0 關注
- 214 瀏覽
添加回答
舉報
0/150
提交
取消