channel(一)
? channel用于goroutines之間的通信,讓它們之間可以進行資料交換,像管道一樣,一個goroutine_A向channel_A中放資料,另一個goroutine_B從channel_A取資料
channel 基本語法
// 因為channel是指標型別的資料型別,所以通過make來分配記憶體
// 使用make宣告一個channel,里面可以存放string型別的資料
channel := make(chan string)
// 將tmp送到channel中
channel <- tmp
// 從channel中接受資料給tmp
tmp := <- channel
// 從channel中接受資料給tmp,如果沒有接受到則ok值為false
tmp,ok := <- channel
// 關閉通道channel
close(channel)
無緩沖的通道
? 沒有緩沖的通道,如果routine A向通道中發送了一個資料,那么必須等到這個資料被其他routine 取出之后,才能繼續往通道里發送,嚴格遵循”一進一出“原則,這也就要求兩個routine 在同時對同一個通道進行寫操作和取操作
- sender端向channel中send一個資料,然后阻塞,直到receiver端將此資料receive
- receiver端一直阻塞,直到sender端向channel發送了一個資料
// 兩個routine分別對一個通道進行取放操作,并且對里面的資料+1,到2000截至
// 嚴格遵循“一進一出”
func Routine01(wg *sync.WaitGroup, count chan int) {
defer wg.Done()
for {
// 從通道中拿取資料
res, ok := <-count
if !ok {
// 說明通道中已經沒有資料,或者已被關閉
fmt.Println("finish!")
break
}
fmt.Println(res)
if res == 2000 {
close(count)
break
}
count <- res + 1
}
}
func main() {
var wg sync.WaitGroup
// 新建一個無緩沖的通道count
count := make(chan int)
wg.Add(2)
// 創建兩個協程
for i := 0; i < 2; i++ {
go Routine01(&wg, count)
}
// 給管道里送一個資料,來開始操作
count <- 1
wg.Wait()
}
有緩沖的通道
? 有緩沖的通道,可以控制里面的緩沖區大小,可以借助通道實作異步的取放操作
- 容量:表示buffered channel最多可以緩沖多少個資料
- 長度:表示buffered channel當前已緩沖多少個資料
- 創建buffered channel的方式為
make(chan TYPE,CAP)
// 新建Routine來模擬機器人作業
func Routine02(wg *sync.WaitGroup, count chan string) {
defer wg.Done()
for {
// 從通道中分配作業
tmp, ok := <-count
if !ok {
// 代表通道已經空了,或者已被關閉
fmt.Println("No task else!")
break
}
fmt.Println(tmp + " start!")
time.Sleep(200 * time.Millisecond)
fmt.Println(tmp + " done!")
}
}
func main() {
var wg sync.WaitGroup
// 新建一個緩沖區大小為5的通道,來管理作業
count := make(chan string, 5)
wg.Add(2)
fmt.Println("Work start!")
// 往緩沖區中放一系列待完成的作業
for i := 0; i < 5; i++ {
tmp := fmt.Sprintf("Task %d", i)
count <- tmp
fmt.Println(tmp + " in!")
}
for i := 0; i < 2; i++ {
go functions.Routine(&wg, count)
}
// 關閉通道
close(count)
wg.Wait()
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/551705.html
標籤:其他
上一篇:線上FullGC問題排查實踐——手把手教你排查線上問題
下一篇:返回列表
