mirror of
https://github.com/gopl-zh/gopl-zh.github.com.git
synced 2025-12-20 04:34:20 +08:00
make loop
This commit is contained in:
@@ -68,7 +68,7 @@ func walkDir(dir string, n *sync.WaitGroup, fileSizes chan<- int64) {
|
||||
|
||||
在walkDir函數的循環中我們對取消狀態進行輪詢可以帶來明顯的益處,可以避免在取消事件發生時還去創建goroutine。取消本身是有一些代價的;想要快速的響應需要對程序邏輯進行侵入式的脩改。確保在取消發生之後不要有代價太大的操作可能會需要脩改你代碼里的很多地方,但是在一些重要的地方去檢査取消事件也確實能帶來很大的好處。
|
||||
|
||||
對這個程序的一個簡單的性能分析可以揭示瓶頸在dirents函數中穫取一個信號量。下面的select可以讓這種操作可以被取消,併且可以將取消時的延遲從幾百毫秒降低到幾十毫秒。
|
||||
對這個程序的一個簡單的性能分析可以揭示瓶頸在dirents函數中獲取一個信號量。下面的select可以讓這種操作可以被取消,併且可以將取消時的延遲從幾百毫秒降低到幾十毫秒。
|
||||
|
||||
```go
|
||||
func dirents(dir string) []os.FileInfo {
|
||||
@@ -82,7 +82,7 @@ func dirents(dir string) []os.FileInfo {
|
||||
}
|
||||
```
|
||||
|
||||
現在當取消發生時,所有後台的goroutine都會迅速停止併且主函數會返迴。當然,當主函數返迴時,一個程序會退出,而我們又無法在主函數退出的時候確認其已經釋放了所有的資源(譯註:因爲程序都退出了,你的代碼都沒法執行了)。這里有一個方便的竅門我們可以一用:取代掉直接從主函數返迴,我們調用一個panic,然後runtime會把每一個goroutine的棧dump下來。如果main goroutine是唯一一個剩下的goroutine的話,他會清理掉自己的一切資源。但是如果還有其它的goroutine沒有退出,他們可能沒辦法被正確地取消掉,也有可能被取消但是取消操作會很花時間;所以這里的一個調研還是很有必要的。我們用panic來穫取到足夠的信息來驗證我們上面的判斷,看看最終到底是什麽樣的情況。
|
||||
現在當取消發生時,所有後台的goroutine都會迅速停止併且主函數會返迴。當然,當主函數返迴時,一個程序會退出,而我們又無法在主函數退出的時候確認其已經釋放了所有的資源(譯註:因爲程序都退出了,你的代碼都沒法執行了)。這里有一個方便的竅門我們可以一用:取代掉直接從主函數返迴,我們調用一個panic,然後runtime會把每一個goroutine的棧dump下來。如果main goroutine是唯一一個剩下的goroutine的話,他會清理掉自己的一切資源。但是如果還有其它的goroutine沒有退出,他們可能沒辦法被正確地取消掉,也有可能被取消但是取消操作會很花時間;所以這里的一個調研還是很有必要的。我們用panic來獲取到足夠的信息來驗證我們上面的判斷,看看最終到底是什麽樣的情況。
|
||||
|
||||
練習8.10: HTTP請求可能會因http.Request結構體中Cancel channel的關閉而取消。脩改8.6節中的web crawler來支持取消http請求。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user