回到简体

This commit is contained in:
chai2010
2016-02-15 11:06:34 +08:00
parent 9e878f9944
commit 2b37b23285
177 changed files with 2354 additions and 2354 deletions

View File

@@ -1,10 +1,10 @@
### 8.4.2. 串的ChannelsPipeline
### 8.4.2. 串的ChannelsPipeline
Channels也可以用於將多個goroutine接在一起,一Channels的出作下一Channels的入。這種串聯的Channels就是所的管道pipeline。下面的程序用兩個channels將三個goroutine串聯起來,如8.1所示。
Channels也可以用于将多个goroutine接在一起,一Channels的出作下一Channels的入。这种串联的Channels就是所的管道pipeline。下面的程序用两个channels将三个goroutine串联起来,如8.1所示。
![](../images/ch8-01.png)
第一goroutine是一個計數器,用生成0、1、2、……形式的整序列,然後通過channel將該整數序列發送給第二goroutine第二goroutine是一求平方的程序,收到的每個整數求平方,然後將平方後的結果通第二channel發送給第三goroutine第三goroutine是一打印程序,打印收到的每個整數。爲了保持例子清晰,我有意選擇了非常簡單的函數,當然三goroutine的算很簡單,在現實中確實沒有必要如此簡單的運算構建三goroutine。
第一goroutine是一个计数器,用生成0、1、2、……形式的整序列,然后通过channel将该整数序列发送给第二goroutine第二goroutine是一求平方的程序,收到的每个整数求平方,然后将平方后的结果通第二channel发送给第三goroutine第三goroutine是一打印程序,打印收到的每个整数。为了保持例子清晰,我有意选择了非常简单的函数,当然三goroutine的算很简单,在现实中确实没有必要如此简单的运算构建三goroutine。
<u><i>gopl.io/ch8/pipeline1</i></u>
```Go
@@ -34,17 +34,17 @@ func main() {
}
```
如您所料,上面的程序生成0、1、4、9、……形式的無窮數列。像這樣的串Channels的管道Pipelines可以用在需要長時間運行的服中,每個長時間運行的goroutine可能包含一死循在不同goroutine的死循環內部使用串的Channels通信。但是,如果我希望通Channels隻發送有限的數列該如何理呢?
如您所料,上面的程序生成0、1、4、9、……形式的无穷数列。像这样的串Channels的管道Pipelines可以用在需要长时间运行的服中,每个长时间运行的goroutine可能包含一死循在不同goroutine的死循环内部使用串的Channels通信。但是,如果我希望通Channels只发送有限的数列该如何理呢?
如果送者知道,有更多的值需要送到channel的,那麽讓接收者也能及知道有多的值可接收是有用的,因接收者可以停止不必要的接收等待。可以通過內置的close函數來關閉channel實現
如果送者知道,有更多的值需要送到channel的,那么让接收者也能及知道有多的值可接收是有用的,因接收者可以停止不必要的接收等待。可以通过内置的close函数来关闭channel实现
```Go
close(naturals)
```
當一個channel被關閉後,再向channel發送數據將導致panic常。當一個被關閉的channel中已經發送的數據都被成功接收後,後續的接收操作不再阻塞,它們會立卽返迴一個零值。關閉上面例子中的naturals變量對應的channel不能止循,它依然收到一個永無休止的零值序列,然後將它們發送給打印者goroutine。
当一个channel被关闭后,再向channel发送数据将导致panic常。当一个被关闭的channel中已经发送的数据都被成功接收后,后续的接收操作不再阻塞,它们会立即返回一个零值。关闭上面例子中的naturals变量对应的channel不能止循,它依然收到一个永无休止的零值序列,然后将它们发送给打印者goroutine。
沒有辦法直接測試一個channel是否被關閉,但是接收操作有一個變體形式:它多接收一個結果,多接收的第二個結果是一個布爾值okture表示成功channels接收到值false表示channels已經被關閉併且里面有值可接收。使用這個特性,我可以改squarer函中的循環代碼,當naturals對應的channel被關閉併沒有值可接收跳出循環,併且也關閉squares對應的channel.
没有办法直接测试一个channel是否被关闭,但是接收操作有一个变体形式:它多接收一个结果,多接收的第二个结果是一个布尔值okture表示成功channels接收到值false表示channels已经被关闭并且里面有值可接收。使用这个特性,我可以改squarer函中的循环代码,当naturals对应的channel被关闭并没有值可接收跳出循环,并且也关闭squares对应的channel.
```Go
// Squarer
@@ -60,9 +60,9 @@ go func() {
}()
```
上面的法是笨拙的,而且這種處理模式很因此Go言的range循可直接在channels上面迭代。使用range循是上面理模式的簡潔語法,它依次channel接收數據,當channel被關閉併且沒有值可接收跳出循
上面的法是笨拙的,而且这种处理模式很因此Go言的range循可直接在channels上面迭代。使用range循是上面理模式的简洁语法,它依次channel接收数据,当channel被关闭并且没有值可接收跳出循
在下面的改中,我們的計數器goroutine生成100個含數字的序列,然後關閉naturals對應的channel這將導致計算平方的squarer對應的goroutine可以正常止循環併關閉squares對應的channel。在一個更複雜的程序中,可以通defer語句關閉對應的channel。主goroutine也可以正常止循環併退出程序。
在下面的改中,我们的计数器goroutine生成100个含数字的序列,然后关闭naturals对应的channel这将导致计算平方的squarer对应的goroutine可以正常止循环并关闭squares对应的channel。在一个更复杂的程序中,可以通defer语句关闭对应的channel。主goroutine也可以正常止循环并退出程序。
<u><i>gopl.io/ch8/pipeline2</i></u>
```Go
@@ -93,8 +93,8 @@ func main() {
}
```
實你併不需要關閉每一channel。隻要當需要告接收者goroutine所有的數據已經全部發送時才需要關閉channel。不管一channel是否被關閉,當它沒有被引用時將會被Go言的垃圾自動迴收器收。(不要將關閉一個打開文件的操作和關閉一個channel操作混淆。對於每個打開的文件,都需要在不使用的使用調用對應的Close方法來關閉文件。)
实你并不需要关闭每一channel。只要当需要告接收者goroutine所有的数据已经全部发送时才需要关闭channel。不管一channel是否被关闭,当它没有被引用时将会被Go言的垃圾自动回收器收。(不要将关闭一个打开文件的操作和关闭一个channel操作混淆。对于每个打开的文件,都需要在不使用的使用调用对应的Close方法来关闭文件。)
視圖重複關閉一個channel將導致panic常,視圖關閉一個nil值的channel也將導致panic常。關閉一個channels還會觸發一個廣播機製,我們將在8.9節討論
视图重复关闭一个channel将导致panic常,视图关闭一个nil值的channel也将导致panic常。关闭一个channels还会触发一个广播机制,我们将在8.9节讨论