很多時候我們經過使用有緩衝channel作為通訊控制的功能,以至有一些誤解和坑出現。
執行下面**。
1
2
3
4
5
6
7
8
9
10
11
12
13
package
mainimport (
"time"
"math/rand"
)func main()
}() go getcache(cache) go getcache(cache) go getcache(cache)
time.sleep(
3
*time.second)
}func getcache(cache <-chan
int
)
}
}
多執行幾次看看結果,並不是每一次都是可以順序輸出的,有快取channel是亂序的。因為這裡讓一些同學誤解了,我在此多解釋一下。
針對通道的傳送和接收操作都是可能造成相關的goroutine阻塞。試想一下,有多個goroutine向同乙個channel傳送資料而被阻塞,如果還channel有多餘的快取空間時候,最早被阻塞的goroutine會最先被喚醒。也就是說,這裡的喚醒順序與傳送操作的開始順序是一致的,對接收操作而言亦為如此。無論是傳送還是接收操作,執行時系統每次只會喚醒乙個goroutine。 而這裡的亂序是指,如果像使用channel快取中多個goroutine實現順序是正確的,因為每乙個goroutine搶到處理器的時間點不一致,所以不能保證順序。
如下**。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package
mainimport (
"fmt"
"sync"
"time"
)var wg = sync.waitgroup{}func main() func insert(bf chan string)
wg.done()
}func sprint(s string) func get(bf chan string)
}()
}
}
很多同學乍一看以為定義了
1bf := make(chan string,
64
)
就是說該程式的併發度控制在了64,執行就會發現記憶體一直在增長。 因為get()函式中啟動的goroutine會越來越多,因為get()每讀取乙個資料,insert()就會往channel插入一條資料,此時併發度就不是64了。 需要修改為:
12
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package
mainimport (
"fmt"
"sync"
"time"
)var wg = sync.waitgroup{}func main()
wg.wait()
}func insert(bf chan string)
wg.done()
}func sprint(s string) func get1(bf chan string)
}
}
golang中併發sync和channel
golang中實現併發非常簡單,只需在需要併發的函式前面新增關鍵字 go 但是如何處理go併發機制中不同goroutine之間的同步與通訊,golang 中提供了sync包和channel機制來解決這一問題 sync 包提供了互斥鎖這類的基本的同步原語.除 once 和 waitgroup 之外的型...
golang中併發sync和channel
golang中實現併發非常簡單,只需在需要併發的函式前面新增關鍵字 go 但是如何處理go併發機制中不同goroutine之間的同步與通訊,golang 中提供了sync包和channel機制來解決這一問題 sync 包提供了互斥鎖這類的基本的同步原語.除 once 和 waitgroup 之外的型...
golang中併發sync和channel
golang中實現併發非常簡單,只需在需要併發的函式前面新增關鍵字 go 但是如何處理go併發機制中不同goroutine之間的同步與通訊,golang 中提供了sync包和channel機制來解決這一問題 sync 包提供了互斥鎖這類的基本的同步原語.除 once 和 waitgroup 之外的型...