技術實踐——教你用100行寫一個 go 的協程池 (任務池)!!!
點選這裡,檢視封裝 GetCap() 方法等重要內容
實現
Talk is cheap. Show me the code.
任務的定義
任務要包含需要執行的函式、以及函式要傳的引數, 因為引數型別、個數不確定, 這裡使用可變引數和空介面的形式
type Task struct {
Handler func(v ...interface{})
Params []interface{}
}
任務池的定義
任務池的定義包括了池的容量 capacity、當前執行的 worker(goroutine)數量 runningWorkers、任務佇列(channel)taskC、關閉任務池的 channel closeC 以及任務池的狀態 state(執行中或已關閉, 用於安全關閉任務池)
type Pool struct {
capacity uint64
runningWorkers uint64
state int64
taskC chan *Task
closeC chan bool
}
任務池的建構函式:
var ErrInvalidPoolCap = errors.New("invalid pool cap")
const (
RUNNING = 1
STOPED = 0
)
func NewPool(capacity uint64) (*Pool, error) {
if capacity <= 0 {
return nil, ErrInvalidPoolCap
}
return &Pool{
capacity: capacity,
state: RUNNING,
// 初始化任務佇列, 佇列長度為容量
taskC: make(chan *Task, capacity),
closeC: make(chan bool),
}, nil
}
啟動 worker
新建 run() 方法作為啟動 worker 的方法:
func (p *Pool) run() {
p.runningWorkers++ // 執行中的任務加一
go func() {
defer func() {
p.runningWorkers-- // worker 結束, 執行中的任務減一
}()
for {
select { // 阻塞等待任務、結束訊號到來
case task, ok :=
上述程式碼中, runningWorkers 的加減直接使用了自增運算, 但是考慮到啟動多個 worker 時, runningWorkers 就會有資料競爭, 所以我們使用 sync.atomic 包來保證 runningWorkers 的自增操作是原子的。
對 runningWorkers 的操作進行封裝:
func (p *Pool) incRunning() { // runningWorkers + 1
atomic.AddUint64(&p.runningWorkers, 1)
}
func (p *Pool) decRunning() { // runningWorkers - 1
atomic.AddUint64(&p.runningWorkers, ^uint64(0))
}
func (p *Pool) GetRunningWorkers() uint64 {
return atomic.LoadUint64(&p.runningWorkers)
}
打鐵乘熱, 對於 capacity 的操作也考慮資料競爭, 封裝 GetCap() 方法:
關鍵字:網路協議 Java Go
相關文章
- go 任務池Go
- Go實戰準備工作---建立協程池和定時任務Go
- go 協程初體驗 [模擬使用者執行緒池,處理 50 個任務 jobs]Go執行緒
- Go實戰準備工作---建立攜程池和定時任務Go
- Spring 非同步執行緒池、排程任務執行緒池配置Spring非同步執行緒
- 任務池
- JavaScript 任務池JavaScript
- Golang協程池(workpool)實現Golang
- ants——Go語言的高效能協程池Go
- 手寫一個執行緒池,帶你學習ThreadPoolExecutor執行緒池實現原理執行緒thread
- java執行緒池實踐Java執行緒
- jdk排程任務執行緒池ScheduledThreadPoolExecutor工作原理解析JDK執行緒thread
- golang協程池設計Golang
- JAVA執行緒池原理原始碼解析—為什麼啟動一個執行緒池,提交一個任務後,Main方法不會退出?Java執行緒原始碼AI
- 100行Java程式碼構建一個執行緒池Java執行緒
- 執行緒池原理與實踐執行緒
- Springboot非同步任務執行緒池Spring Boot非同步執行緒
- 從入門到掉坑:Go 記憶體池/物件池技術介紹Go記憶體物件
- Unity物件池技術(原理+實戰)Unity物件
- Spring Boot使用執行緒池處理事務任務Spring Boot執行緒
- 技術實踐:教你用Python搭建gRPC服務PythonRPC
- 高併發面試:執行緒池的七大引數?手寫一個執行緒池?面試執行緒
- java常量池技術Java
- Mix XWP V1.1 - Go 通用動態協程池 WorkerPoolGo
- Java幾種執行緒池及任務佇列Java執行緒佇列
- 執行緒池遇到父子任務,有大坑,要注意!執行緒
- Java 執行緒池的理論與實踐Java執行緒
- 基於 swoole 協程的 MySQL 連線池MySql
- ants - 目前開源最優的協程池
- 池化技術總結
- Unity寫個多用物件池Unity物件
- 自定義物件池實踐物件
- 物件池技術和通用實現GenericObjectPool物件Object
- 【從0開始編寫webserver·基礎篇#01】為什麼需要執行緒池?寫一個執行緒池吧WebServer執行緒
- Go程式設計模式三—Fan-Out模式與協程池結合Go程式設計設計模式
- 手寫執行緒池,對照學習ThreadPoolExecutor執行緒池實現原理!執行緒thread
- Swoole 實戰:MySQL 查詢器的實現(協程連線池版)MySql
- 深入分析3種執行緒池執行任務的邏輯方法執行緒