亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么在并行處理時可以在 Go 中重用通道?

為什么在并行處理時可以在 Go 中重用通道?

Go
素胚勾勒不出你 2021-12-20 15:37:10
這是官方教程中的代碼片段package mainimport "fmt"func sum(s []int, c chan int) {    sum := 0    for _, v := range s {        sum += v    }    c <- sum // send sum to c}func main() {    s := []int{7, 2, 8, -9, 4, 0}    c := make(chan int)    go sum(s[:len(s)/2], c)    go sum(s[len(s)/2:], c)    x, y := <-c, <-c // receive from c    fmt.Println(x, y, x+y)}既然我們是并行計算的,每個線程都把結果保存到同一個通道中,這不是把數據搞砸了嗎?
查看完整描述

2 回答

?
慕標5832272

TA貢獻1966條經驗 獲得超4個贊

通道操作是 goroutine 安全的。你可以在任何 goroutine 中讀/寫/關閉,而不會破壞任何進出通道的東西?;旧?,通道是同步點。無緩沖通道(如您的情況)將在每次寫入和讀取時阻塞。當您編寫代碼時,您的代碼會阻塞并等待有人開始在另一端閱讀。當您閱讀您的代碼時,您的代碼會阻塞并等待有人開始在另一端編寫。

在您的情況下,goroutines 中的計算將同時完成(不需要并行),但會在通道寫入時阻塞。您的主要 goroutine 將在第一次讀取時阻塞,讀取值。在第二次讀取時阻塞,讀取值。

即使您使用緩沖通道 - c := make(chan int, 2). 您的 goroutine 將完成計算,將結果寫入通道而不阻塞并終止。什么都不會被破壞。與此同時,主 goroutine 將阻塞通道讀取并等待有人寫入它。

我建議你閱讀Effective go , Go Concurrency Patterns并嘗試A Tour of Go


查看完整回答
反對 回復 2021-12-20
?
長風秋雁

TA貢獻1757條經驗 獲得超7個贊

確實,當您從兩個不同的 goroutine 通過一個通道發送兩個值時,不一定保證排序(除非您已經做了其他事情來協調它們的發送)。

但是,在此示例中,排序根本無關緊要。通道上正在發送兩個值:前半部分的總和和第二部分的總和。

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

由于這兩個值唯一用于計算總和,因此順序根本無關緊要。事實上,如果您運行該示例的次數足夠多,您應該會看到它x并且y經常被交換,但總和x+y始終相同。


查看完整回答
反對 回復 2021-12-20
  • 2 回答
  • 0 關注
  • 199 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號