mirror of
https://github.com/gopl-zh/gopl-zh.github.com.git
synced 2025-12-18 03:34:19 +08:00
zz
This commit is contained in:
@@ -27,7 +27,7 @@ func makeThumbnails(filenames []string) {
|
||||
|
||||
顯然我們處理文件的順序無關緊要,因爲每一個圖片的拉伸操作和其它圖片的處理操作都是彼此獨立的。像這種子問題都是完全彼此獨立的問題被叫做易併行問題(譯註:embarrassingly parallel,直譯的話更像是尷尬併行)。易併行問題是最容易被實現成併行的一類問題(廢話),併且是最能夠享受併發帶來的好處,能夠隨着併行的規模線性地擴展。
|
||||
|
||||
下面讓我們併行地執行這些操作,從而將文件IO的延遲隱藏掉,併用上多覈cpu的計算能力來拉伸圖像。我們的第一個併發程序隻是使用了一個go關鍵字。這里我們先忽略掉錯誤,之後再進行處理。
|
||||
下面讓我們併行地執行這些操作,從而將文件IO的延遲隱藏掉,併用上多核cpu的計算能力來拉伸圖像。我們的第一個併發程序隻是使用了一個go關鍵字。這里我們先忽略掉錯誤,之後再進行處理。
|
||||
|
||||
```go
|
||||
// NOTE: incorrect!
|
||||
@@ -186,4 +186,4 @@ sizes channel攜帶了每一個文件的大小到main goroutine,在main gorout
|
||||
|
||||
練習8.4: 脩改reverb2服務器,在每一個連接中使用sync.WaitGroup來計數活躍的echo goroutine。當計數減爲零時,關閉TCP連接的寫入,像練習8.3中一樣。驗證一下你的脩改版netcat3客戶端會一直等待所有的併發“喊叫”完成,卽使是在標準輸入流已經關閉的情況下。
|
||||
|
||||
練習8.5: 使用一個已有的CPU綁定的順序程序,比如在3.3節中我們寫的Mandelbrot程序或者3.2節中的3-D surface計算程序,併將他們的主循環改爲併發形式,使用channel來進行通信。在多覈計算機上這個程序得到了多少速度上的改進?使用多少個goroutine是最合適的呢?
|
||||
練習8.5: 使用一個已有的CPU綁定的順序程序,比如在3.3節中我們寫的Mandelbrot程序或者3.2節中的3-D surface計算程序,併將他們的主循環改爲併發形式,使用channel來進行通信。在多核計算機上這個程序得到了多少速度上的改進?使用多少個goroutine是最合適的呢?
|
||||
|
||||
@@ -59,7 +59,7 @@ https://golang.org/blog/
|
||||
|
||||
最初的錯誤信息是一個讓人莫名的DNS査找失敗,卽使這個域名是完全可靠的。而隨後的錯誤信息揭示了原因:這個程序一次性創建了太多網絡連接,超過了每一個進程的打開文件數限製,旣而導致了在調用net.Dial像DNS査找失敗這樣的問題。
|
||||
|
||||
這個程序實在是太他媽併行了。無窮無盡地併行化併不是什麽好事情,因爲不管怎麽説,你的繫統總是會有一個些限製因素,比如CPU覈心數會限製你的計算負載,比如你的硬盤轉軸和磁頭數限製了你的本地磁盤IO操作頻率,比如你的網絡帶寬限製了你的下載速度上限,或者是你的一個web服務的服務容量上限等等。爲了解決這個問題,我們可以限製併發程序所使用的資源來使之適應自己的運行環境。對於我們的例子來説,最簡單的方法就是限製對links.Extract在同一時間最多不會有超過n次調用,這里的n是fd的limit-20,一般情況下。這個一個夜店里限製客人數目是一個道理,隻有當有客人離開時,才會允許新的客人進入店內(譯註:作者你個老流氓)。
|
||||
這個程序實在是太他媽併行了。無窮無盡地併行化併不是什麽好事情,因爲不管怎麽説,你的繫統總是會有一個些限製因素,比如CPU核心數會限製你的計算負載,比如你的硬盤轉軸和磁頭數限製了你的本地磁盤IO操作頻率,比如你的網絡帶寬限製了你的下載速度上限,或者是你的一個web服務的服務容量上限等等。爲了解決這個問題,我們可以限製併發程序所使用的資源來使之適應自己的運行環境。對於我們的例子來説,最簡單的方法就是限製對links.Extract在同一時間最多不會有超過n次調用,這里的n是fd的limit-20,一般情況下。這個一個夜店里限製客人數目是一個道理,隻有當有客人離開時,才會允許新的客人進入店內(譯註:作者你個老流氓)。
|
||||
|
||||
我們可以用一個有容量限製的buffered channel來控製併發,這類似於操作繫統里的計數信號量概念。從概念上講,channel里的n個空槽代表n個可以處理內容的token(通行證),從channel里接收一個值會釋放其中的一個token,併且生成一個新的空槽位。這樣保證了在沒有接收介入時最多有n個發送操作。(這里可能我們拿channel里填充的槽來做token更直觀一些,不過還是這樣吧~)。由於channel里的元素類型併不重要,我們用一個零值的struct{}來作爲其元素。
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 第八章 Goroutines和Channels
|
||||
|
||||
併發程序指的是同時做好幾件事情的程序,隨着硬件的發展,併發程序顯得越來越重要。Web服務器會一次處理成韆上萬的請求。平闆電腦和手機app在渲染用戶動畵的同時,還會後台執行各種計算任務和網絡請求。卽使是傳統的批處理問題--讀取數據,計算,寫輸出--現在也會用併發來隱藏掉I/O的操作延遲充分利用現代計算機設備的多覈,盡管計算機的性能每年都在增長,但併不是線性。
|
||||
併發程序指的是同時做好幾件事情的程序,隨着硬件的發展,併發程序顯得越來越重要。Web服務器會一次處理成韆上萬的請求。平闆電腦和手機app在渲染用戶動畵的同時,還會後台執行各種計算任務和網絡請求。卽使是傳統的批處理問題--讀取數據,計算,寫輸出--現在也會用併發來隱藏掉I/O的操作延遲充分利用現代計算機設備的多核,盡管計算機的性能每年都在增長,但併不是線性。
|
||||
|
||||
Go語言中的併發程序可以用兩種手段來實現。這一章會講解goroutine和channel,其支持“順序進程通信”(communicating sequential processes)或被簡稱爲CSP。CSP是一個現代的併發編程模型,在這種編程模型中值會在不同的運行實例(goroutine)中傳遞,盡管大多數情況下被限製在單一實例中。第9章會覆蓋到更爲傳統的併發模型:多線程共享內存,如果你在其它的主流語言中寫過併發程序的話可能會更熟悉一些。第9章同時會講一些本章不會深入的併發程序帶來的重要風險和陷阱。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user