iT邦幫忙

0

[Go] goroutine有啟動順序嗎?

我在A Tour of 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
	fmt.Println(a)
}

func main() {
	a := []int{7, 2, 8, -9, 4, 0}

	c := make(chan int)
	go sum(a[:len(a)/2], c)
	go sum(a[len(a)/2:], c)
	x, y := <-c, <-c // receive from c

	fmt.Println(x, y, x+y)
}

執行結果為

[-9 4 0]
[7 2 8]
-5 17 12

代表說sum(a[len(a)/2:], c)比go sum(a[:len(a)/2], c)早執行完,如果我將這兩行互換如下

	go sum(a[len(a)/2:], c)
    go sum(a[:len(a)/2], c)

運行結果為反過來go sum(a[:len(a)/2], c)比go sum(a[len(a)/2:], c)早執行完

[7 2 8]
[-9 4 0]
17 -5 12

請問goroutine是有順序的嗎?

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

0
listennn08
iT邦高手 5 級 ‧ 2020-05-19 09:20:28
最佳解答

你的方式其實無法明顯看出他們的執行順序
如果把他分開 你會發現他是照順序執行的

func main() {
	a := []int{7, 2, 8, -9, 4, 0}

	c := make(chan int)
	go sum(a[:len(a)/2], c)
    x:= <-c
    fmt.Println(x)
    
	go sum(a[len(a)/2:], c)
	y := <-c // receive from c
    fmt.Println(y)
	fmt.Println(x, y, x+y)
}

參考

wrxue iT邦好手 1 級 ‧ 2020-05-19 09:21:45 檢舉

但為何總是下面的go先執行完,是巧合嗎?明明內容(都處理3個element)一樣

wrxue
我的理解是因為 goroutine 屬於多執行緒 也不會同步執行

go sum(a[:len(a)/2], c)
go sum(a[len(a)/2:], c)

是併發呼叫但沒辦法保證誰先執行完成
goroutine

whitefloor iT邦研究生 2 級 ‧ 2020-05-23 16:07:56 檢舉

樓上正解

我要發表回答

立即登入回答