建立乙個協成復用,限制協成數量的協成池
package pool
import (
"fmt"
)type pool inte***ce
type pool struct // 計數,限制協成數
}func new(size int) pool , size), }}
func (p *pool) schedule(task func()) error {}:
go p.worker(task)
} return nil
}func (p *pool) worker(task func()) ()
for
}
1. p.work時無緩衝,所以第一次呼叫schedule時case p.work <- task: 由於沒有協成讀work,就不會寫入,就為false,2. p.sem因為有緩衝區,不需要有讀協成讀就可以寫入,所以會執行case p.sem <- struct{}{},往sem寫入乙個空物件,接著通過go p.workder(task)開啟乙個協成處理task。
3. task處理結束後,協成不銷毀,會停在task = <-p.work等待接收p.work裡的任務
2. 第二次呼叫schedule,如果第一次建立的協成等待接收新的task(task = <-p.work),就會執行case p.work <- task,往work的channel寫資料,協成就能從p.work取到(task = <-p.work)task執行,不會開啟新的協成。
3. 如果task執行時間比較久,第二次呼叫schedule時,task()還未執行完,也就是還未執行到task = <-p.work,那麼case p.work <- task將無法寫入,當p.sem緩衝區沒滿(還未達到限制size)就會執行case p.sem <- struct{}{},開啟新的協成執行task.
4. 當p.sem緩衝區滿了,也就是說達到限制的最大數時,schedule將會pending,直到某個協成執行到task = <-p.work接收任務
5. defer func() ()是用在**,在一些情況下,希望協成銷毀,就可以跳出for迴圈,sem讀出資料,也就是執行緒數數-1
go簡單協程池實現
為防止無限制開啟gorouting造成的cpu效能浪費以及更嚴重的記憶體溢位和程式崩潰,這裡加單實現一下協程池 深入理解 流程圖 實現 package main import fmt time 有關任務的功能 定義乙個任務型別 type task struct 建立乙個task任務 func new...
go 協程等待
sync包提供了基本的同步基元,如互斥鎖 但是這裡不是討論執行緒通訊的問題 而執行緒通訊應使用channel 以前使用time.sleep 來保證執行緒執行完成,顯然執行緒執行所需要的時間不確定 sync裡面有乙個waitgroup,它是乙個結構體,可以用於等待執行緒執行 這樣不用去估算執行緒需要執...
Go 協程 通道
目錄 go 協程 go 通道 go 協程go 協程可以看作是輕量級執行緒。與執行緒相比,建立乙個go協程的成本很小。因此在go應用中,常常會看到有數以千計的go協程併發地執行 go 協程相比於執行緒的優勢 啟動乙個go協程 在呼叫函式和方法時,在前面加上關鍵字go,可以讓乙個新的go協程併發執行 p...