make loop

This commit is contained in:
chai2010
2015-12-28 15:57:07 +08:00
parent 77148f84d4
commit ba7261d140
25 changed files with 44 additions and 44 deletions

View File

@@ -62,7 +62,7 @@ https://golang.org/blog/
我們可以用一個有容量限製的buffered channel來控製併發這類似於操作繫統里的計數信號量概念。從概念上講channel里的n個空槽代表n個可以處理內容的token(通行證)從channel里接收一個值會釋放其中的一個token併且生成一個新的空槽位。這樣保證了在沒有接收介入時最多有n個發送操作。(這里可能我們拿channel里填充的槽來做token更直觀一些不過還是這樣吧~)。由於channel里的元素類型併不重要我們用一個零值的struct{}來作爲其元素。
讓我們重寫crawl函數將對links.Extract的調用操作用取、釋放token的操作包裹起來來確保同一時間對其隻有20個調用。信號量數量和其能操作的IO資源數量應保持接近。
讓我們重寫crawl函數將對links.Extract的調用操作用取、釋放token的操作包裹起來來確保同一時間對其隻有20個調用。信號量數量和其能操作的IO資源數量應保持接近。
```go
gopl.io/ch8/crawl2

View File

@@ -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請求。

View File

@@ -55,7 +55,7 @@ func broadcaster() {
}
```
broadcaster監聽來自全局的entering和leaving的channel來知客戶端的到來和離開事件。當其接收到其中的一個事件時會更新clients集合當該事件是離開行爲時它會關閉客戶端的消息發出channel。broadcaster也會監聽全局的消息channel所有的客戶端都會向這個channel中發送消息。當broadcaster接收到什麽消息時就會將其廣播至所有連接到服務端的客戶端。
broadcaster監聽來自全局的entering和leaving的channel來知客戶端的到來和離開事件。當其接收到其中的一個事件時會更新clients集合當該事件是離開行爲時它會關閉客戶端的消息發出channel。broadcaster也會監聽全局的消息channel所有的客戶端都會向這個channel中發送消息。當broadcaster接收到什麽消息時就會將其廣播至所有連接到服務端的客戶端。
現在讓我們看看每一個客戶端的goroutine。handleConn函數會爲它的客戶端創建一個消息發出channel併通過entering channel來通知客戶端的到來。然後它會讀取客戶端發來的每一行文本併通過全局的消息channel來將這些文本發送出去併爲每條消息帶上發送者的前綴來標明消息身份。當客戶端發送完畢後handleConn會通過leaving這個channel來通知客戶端的離開併關閉連接。