mirror of
https://github.com/gopl-zh/gopl-zh.github.com.git
synced 2025-12-18 19:54:21 +08:00
rebuild
This commit is contained in:
@@ -21,6 +21,10 @@
|
||||
<link rel="stylesheet" href="../gitbook/style.css">
|
||||
|
||||
|
||||
<link rel="stylesheet" href="../gitbook/plugins/gitbook-plugin-katex/katex.min.css">
|
||||
|
||||
|
||||
|
||||
<link rel="stylesheet" href="../gitbook/plugins/gitbook-plugin-highlight/website.css">
|
||||
|
||||
|
||||
@@ -44,7 +48,7 @@
|
||||
<body>
|
||||
|
||||
|
||||
<div class="book" data-level="8.8" data-chapter-title="示例: 併發的字典遍歷" data-filepath="ch8/ch8-08.md" data-basepath=".." data-revision="Fri Dec 25 2015 12:32:44 GMT+0800 (中国标准时间)">
|
||||
<div class="book" data-level="8.8" data-chapter-title="示例: 併發的字典遍歷" data-filepath="ch8/ch8-08.md" data-basepath=".." data-revision="Mon Dec 28 2015 16:03:52 GMT+0800 (中国标准时间)">
|
||||
|
||||
|
||||
<div class="book-summary">
|
||||
@@ -238,7 +242,7 @@
|
||||
|
||||
<b>1.5.</b>
|
||||
|
||||
穫取URL
|
||||
獲取URL
|
||||
</a>
|
||||
|
||||
|
||||
@@ -253,7 +257,7 @@
|
||||
|
||||
<b>1.6.</b>
|
||||
|
||||
併發穫取多個URL
|
||||
併發獲取多個URL
|
||||
</a>
|
||||
|
||||
|
||||
@@ -802,7 +806,7 @@
|
||||
|
||||
<b>5.10.</b>
|
||||
|
||||
Recover捕穫異常
|
||||
Recover捕獲異常
|
||||
</a>
|
||||
|
||||
|
||||
@@ -1315,7 +1319,7 @@
|
||||
|
||||
<b>8.9.</b>
|
||||
|
||||
併發的退齣
|
||||
併發的退出
|
||||
</a>
|
||||
|
||||
|
||||
@@ -1834,7 +1838,7 @@
|
||||
|
||||
<b>12.7.</b>
|
||||
|
||||
穫取結構體字段標識
|
||||
獲取結構體字段標識
|
||||
</a>
|
||||
|
||||
|
||||
@@ -2046,7 +2050,7 @@
|
||||
}
|
||||
</code></pre>
|
||||
<p>ioutil.ReadDir函數會返迴一個os.FileInfo類型的slice,os.FileInfo類型也是os.Stat這個函數的返迴值。對每一個子目録而言,walkDir會遞歸地調用其自身,併且會對每一個文件也遞歸調用。walkDir函數會向fileSizes這個channel發送一條消息。這條消息包含了文件的字節大小。</p>
|
||||
<p>下面的主函數,用了兩個goroutine。後颱的goroutine調用walkDir來遍歷命令行給齣的每一個路徑併最終關閉fileSizes這個channel。主goroutine會對其從channel中接收到的文件大小進行纍加,併輸齣其和。</p>
|
||||
<p>下面的主函數,用了兩個goroutine。後台的goroutine調用walkDir來遍歷命令行給出的每一個路徑併最終關閉fileSizes這個channel。主goroutine會對其從channel中接收到的文件大小進行纍加,併輸出其和。</p>
|
||||
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
|
||||
|
||||
<span class="hljs-keyword">import</span> (
|
||||
@@ -2091,8 +2095,8 @@
|
||||
<pre><code>$ go build gopl.io/ch8/du1
|
||||
$ ./du1 $HOME /usr /bin /etc
|
||||
213201 files 62.7 GB
|
||||
</code></pre><p>如果在運行的時候能夠讓我們知道處理進度的話想必更好。但是,如果簡單地把printDiskUsage函數調用移動到循環里會導致其打印齣成百上韆的輸齣。</p>
|
||||
<p>下面這個du的變種會間歇打印內容,不過隻有在調用時提供了-v的flag纔會顯示程序進度信息。在roots目録上循環的後颱goroutine在這里保持不變。主goroutine現在使用了計時器來每500ms生成事件,然後用select語句來等待文件大小的消息來更新總大小數據,或者一個計時器的事件來打印當前的總大小數據。如果-v的flag在運行時沒有傳入的話,tick這個channel會保持爲nil,這樣在select里的case也就相當於被禁用了。</p>
|
||||
</code></pre><p>如果在運行的時候能夠讓我們知道處理進度的話想必更好。但是,如果簡單地把printDiskUsage函數調用移動到循環里會導致其打印出成百上韆的輸出。</p>
|
||||
<p>下面這個du的變種會間歇打印內容,不過隻有在調用時提供了-v的flag才會顯示程序進度信息。在roots目録上循環的後台goroutine在這里保持不變。主goroutine現在使用了計時器來每500ms生成事件,然後用select語句來等待文件大小的消息來更新總大小數據,或者一個計時器的事件來打印當前的總大小數據。如果-v的flag在運行時沒有傳入的話,tick這個channel會保持爲nil,這樣在select里的case也就相當於被禁用了。</p>
|
||||
<pre><code class="lang-go">gopl.io/ch8/du2
|
||||
<span class="hljs-keyword">var</span> verbose = flag.Bool(<span class="hljs-string">"v"</span>, <span class="hljs-constant">false</span>, <span class="hljs-string">"show verbose progress messages"</span>)
|
||||
|
||||
@@ -2121,7 +2125,7 @@ loop:
|
||||
printDiskUsage(nfiles, nbytes) <span class="hljs-comment">// final totals</span>
|
||||
}
|
||||
</code></pre>
|
||||
<p>由於我們的程序不再使用range循環,第一個select的case必鬚顯式地判斷fileSizes的channel是不是已經被關閉了,這里可以用到channel接收的二值形式。如果channel已經被關閉了的話,程序會直接退齣循環。這里的break語句用到了標籤break,這樣可以同時終結select和for兩個循環;如果沒有用標籤就break的話隻會退齣內層的select循環,而外層的for循環會使之進入下一輪select循環。</p>
|
||||
<p>由於我們的程序不再使用range循環,第一個select的case必鬚顯式地判斷fileSizes的channel是不是已經被關閉了,這里可以用到channel接收的二值形式。如果channel已經被關閉了的話,程序會直接退出循環。這里的break語句用到了標籤break,這樣可以同時終結select和for兩個循環;如果沒有用標籤就break的話隻會退出內層的select循環,而外層的for循環會使之進入下一輪select循環。</p>
|
||||
<p>現在程序會悠閒地爲我們打印更新流:</p>
|
||||
<pre><code>$ go build gopl.io/ch8/du2
|
||||
$ ./du2 -v $HOME /usr /bin /etc
|
||||
@@ -2131,7 +2135,7 @@ $ ./du2 -v $HOME /usr /bin /etc
|
||||
127169 files 52.9 GB
|
||||
175931 files 62.2 GB
|
||||
213201 files 62.7 GB
|
||||
</code></pre><p>然而這個程序還是會花上很長時間纔會結束。無法對walkDir做併行化處理沒什麽别的原因,無非是因爲磁盤繫統併行限製。下面這個第三個版本的du,會對每一個walkDir的調用創建一個新的goroutine。它使用sync.WaitGroup (§8.5)來對仍舊活躍的walkDir調用進行計數,另一個goroutine會在計數器減爲零的時候將fileSizes這個channel關閉。</p>
|
||||
</code></pre><p>然而這個程序還是會花上很長時間才會結束。無法對walkDir做併行化處理沒什麽别的原因,無非是因爲磁盤繫統併行限製。下面這個第三個版本的du,會對每一個walkDir的調用創建一個新的goroutine。它使用sync.WaitGroup (§8.5)來對仍舊活躍的walkDir調用進行計數,另一個goroutine會在計數器減爲零的時候將fileSizes這個channel關閉。</p>
|
||||
<pre><code class="lang-go">gopl.io/ch8/du3
|
||||
<span class="hljs-keyword">func</span> main() {
|
||||
<span class="hljs-comment">// ...determine roots...</span>
|
||||
@@ -2173,7 +2177,7 @@ $ ./du2 -v $HOME /usr /bin /etc
|
||||
<span class="hljs-comment">// ...</span>
|
||||
</code></pre>
|
||||
<p>這個版本比之前那個快了好幾倍,盡管其具體效率還是和你的運行環境,機器配置相關。</p>
|
||||
<p>練習8.9: 編寫一個du工具,每隔一段時間將root目録下的目録大小計算併顯示齣來。</p>
|
||||
<p>練習8.9: 編寫一個du工具,每隔一段時間將root目録下的目録大小計算併顯示出來。</p>
|
||||
|
||||
|
||||
</section>
|
||||
@@ -2187,7 +2191,7 @@ $ ./du2 -v $HOME /usr /bin /etc
|
||||
<a href="../ch8/ch8-07.html" class="navigation navigation-prev " aria-label="Previous page: 基於select的多路複用"><i class="fa fa-angle-left"></i></a>
|
||||
|
||||
|
||||
<a href="../ch8/ch8-09.html" class="navigation navigation-next " aria-label="Next page: 併發的退齣"><i class="fa fa-angle-right"></i></a>
|
||||
<a href="../ch8/ch8-09.html" class="navigation navigation-next " aria-label="Next page: 併發的退出"><i class="fa fa-angle-right"></i></a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -2205,7 +2209,7 @@ $ ./du2 -v $HOME /usr /bin /etc
|
||||
|
||||
<script>
|
||||
require(["gitbook"], function(gitbook) {
|
||||
var config = {"highlight":{},"sharing":{"facebook":true,"twitter":true,"google":false,"weibo":false,"instapaper":false,"vk":false,"all":["facebook","google","twitter","weibo","instapaper"]},"fontsettings":{"theme":"white","family":"sans","size":2}};
|
||||
var config = {"katex":{},"highlight":{},"sharing":{"facebook":true,"twitter":true,"google":false,"weibo":false,"instapaper":false,"vk":false,"all":["facebook","google","twitter","weibo","instapaper"]},"fontsettings":{"theme":"white","family":"sans","size":2}};
|
||||
gitbook.start(config);
|
||||
});
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user