[英]Golang channels, order of execution
我正在學習Go,並且遇到了以下代碼片段:
package main
import "fmt"
func sum(a []int, c chan int) {
sum := 0
for _, v := range a {
sum += v
}
c <- sum // send sum to c
}
func main() {
a := []int{7, 2, 8, -9, 4, 0}
c := make(chan int, 2)
go sum(a[0:3], c)
go sum(a[3:6], c)
x := <-c
y := <-c
// x, y := <-c, <-c // receive from c
fmt.Println(x, y)
}
Output:
-5 17
Program exited.
有人可以告訴我為什么“ sum”函數的第二個調用在第一個調用之前通過通道嗎? 在我看來,輸出應為:
17 -5
我還使用無緩沖通道對此進行了測試,它也給出了相同順序的輸出。 我想念什么?
您正在代碼中調用go例程,但無法確定該例程何時結束並將該值傳遞到緩沖的通道。
由於此代碼是異步的,因此只要例程完成,它將把數據寫入通道,並在另一側讀取。 在上面的示例中,您僅調用兩個go例程,因此行為是確定的,並且在大多數情況下都會以某種方式生成相同的輸出,但是當您增加go例程時,輸出將不會相同,並且順序會有所不同,除非您執行以下操作它同步。
例:
package main
import "fmt"
func sum(a []int, c chan int) {
sum := 0
for _, v := range a {
sum += v
}
c <- sum // send sum to c
}
func main() {
a := []int{7, 2, 8, -9, 4, 2, 4, 2, 8, 2, 7, 2, 99, -32, 2, 12, 32, 44, 11, 63}
c := make(chan int)
for i := 0; i < len(a); i = i + 5 {
go sum(a[i:i+5], c)
}
output := make([]int, 5)
for i := 0; i < 4; i++ {
output[i] = <-c
}
close(c)
fmt.Println(output)
}
此代碼在不同樣本運行中的輸出為
[12 18 0 78 162] [162 78 12 0 18] [12 18 78 162 0]
這是因為goroutines將輸出異步寫入緩沖的通道。
希望這可以幫助。
Goroutine是異步啟動的,它們可以按任何順序寫入通道。 比較容易看出您是否對示例進行了一點修改:
package main
import (
"fmt"
"time"
)
func sum(a []int, c chan int, name string, sleep int) {
fmt.Printf("started goroutine: %s\n", name)
time.Sleep(time.Second * time.Duration(sleep))
sum := 0
for _, v := range a {
sum += v
}
fmt.Printf("about end goroutine: %s\n", name)
c <- sum // send sum to c
}
func main() {
a := []int{7, 2, 8, -9, 4, 0}
c := make(chan int, 2)
go sum(a[0:3], c, "A", 1)
go sum(a[3:6], c, "B", 1)
x := <-c
y := <-c
// x, y := <-c, <-c // receive from c
fmt.Println(x, y)
}
https://play.golang.org/p/dK4DT0iUfzY
結果:
started goroutine: B
started goroutine: A
about end goroutine: A
about end goroutine: B
17 -5
運行golang.org沙箱時,每次都得到相同的結果。 如上所述。 但是,當我在自己的沙箱(在計算機上)上運行相同的代碼段時,有時會更改線程的順序。 這更加令人滿意。 它表明我不能指望任何特定的線程執行順序,這很直觀。 我只是不知道為什么我得到了相同的執行順序,這與線程啟動的順序相反。 我認為這只是golang.org沙盒上抽獎的好運。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.