golang實現(xiàn)協(xié)程池的方法示例
go協(xié)程池可以看成一個被初始化的固定大小的協(xié)程循環(huán)讀取函數(shù)隊列,獲取是否有可供調(diào)用的函數(shù)隊列,如果有,則協(xié)程池中的一個協(xié)程調(diào)用并執(zhí)行該函數(shù),talk is cheap,show me the code。
主體協(xié)程池代碼如下所示:
package goroutine
import (
"context"
"fmt"
"sync"
)
// go實現(xiàn)簡單協(xié)程池
type Pool struct {
ctx context.Context
tasks []fn
lock sync.Locker
}
type fn func()
func Init(ctx context.Context, cnt int) *Pool {
pool := &Pool{
ctx: ctx,
tasks: make([]fn, 0),
lock: NewSpinLock(), //自定義自旋鎖實現(xiàn),如果使用go自帶的鎖,則可能會出現(xiàn)死鎖問題
}
for i := 0; i < cnt; i++ {
go func(pool *Pool, idx int) {
for {
select {
case <-pool.ctx.Done():
fmt.Println("pool exit", idx)
return
default:
fmt.Println("pool exec:", idx)
pool.lock.Lock()
if len(pool.tasks) == 0 {
pool.lock.Unlock()
continue
}
fc := pool.tasks[0]
pool.tasks = pool.tasks[1:]
pool.lock.Unlock()
fc()
}
}
}(pool, i)
}
return pool
}
func (p *Pool) Put(fc fn) {
p.lock.Lock()
p.tasks = append(p.tasks, fc)
p.lock.Unlock()
}
自定義的自旋鎖實現(xiàn)代碼如下:
package goroutine
import (
"runtime"
"sync"
"sync/atomic"
)
type spinLock uint32
const maxBackoff = 16
func (sl *spinLock) Lock() {
backoff := 1
for !atomic.CompareAndSwapUint32((*uint32)(sl), 0, 1) {
// Leverage the exponential backoff algorithm, see https://en.wikipedia.org/wiki/Exponential_backoff.
for i := 0; i < backoff; i++ {
runtime.Gosched()
}
if backoff < maxBackoff {
backoff <<= 1
}
}
}
func (sl *spinLock) Unlock() {
atomic.StoreUint32((*uint32)(sl), 0)
}
// NewSpinLock instantiates a spin-lock.
func NewSpinLock() sync.Locker {
return new(spinLock)
}
測試用的代碼如下所示
package goroutine
import (
"context"
"fmt"
"log"
"strconv"
"sync"
"testing"
"time"
)
func TestPool(t *testing.T) {
ctx := context.Background()
ctx1, cancel := context.WithCancel(ctx)
pool := Init(ctx1, 10)
wg := sync.WaitGroup{}
for i := 100; i >= 0; i-- {
wg.Add(1)
go pool.Put(func() {
wg.Done()
log.Println("hello,world" + strconv.Itoa(i))
})
}
wg.Wait()
cancel()
time.Sleep(time.Second)
}
開發(fā)環(huán)境為goland,運行結(jié)果截圖如下圖:
=== RUN TestPool
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 0
pool exec: 2
pool exec: 0
pool exec: 1
pool exec: 3
pool exec: 4
pool exec: 7
pool exec: 8
pool exec: 5
pool exec: 6
pool exec: 9
2024/08/02 23:06:20 hello,world97
pool exec: 2
2024/08/02 23:06:20 hello,world42
pool exec: 2
2024/08/02 23:06:20 hello,world57
pool exec: 2
2024/08/02 23:06:20 hello,world56
pool exec: 2
2024/08/02 23:06:20 hello,world55
pool exec: 2
2024/08/02 23:06:20 hello,world54
pool exec: 2
2024/08/02 23:06:20 hello,world53
pool exec: 2
2024/08/02 23:06:20 hello,world52
pool exec: 2
2024/08/02 23:06:20 hello,world51
pool exec: 2
2024/08/02 23:06:20 hello,world50
pool exec: 2
2024/08/02 23:06:20 hello,world49
pool exec: 2
2024/08/02 23:06:20 hello,world48
pool exec: 2
2024/08/02 23:06:20 hello,world47
pool exec: 2
2024/08/02 23:06:20 hello,world46
pool exec: 2
2024/08/02 23:06:20 hello,world45
pool exec: 2
2024/08/02 23:06:20 hello,world44
pool exec: 2
2024/08/02 23:06:20 hello,world95
pool exec: 0
2024/08/02 23:06:20 hello,world43
pool exec: 2
2024/08/02 23:06:20 hello,world41
pool exec: 2
2024/08/02 23:06:20 hello,world40
pool exec: 2
2024/08/02 23:06:20 hello,world33
pool exec: 0
2024/08/02 23:06:20 hello,world39
pool exec: 2
2024/08/02 23:06:20 hello,world38
pool exec: 0
2024/08/02 23:06:20 hello,world37
2024/08/02 23:06:20 hello,world36
pool exec: 2
pool exec: 0
2024/08/02 23:06:20 hello,world96
pool exec: 4
2024/08/02 23:06:20 hello,world98
2024/08/02 23:06:20 hello,world99
pool exec: 3
2024/08/02 23:06:20 hello,world94
2024/08/02 23:06:20 hello,world32
pool exec: 7
2024/08/02 23:06:20 hello,world35
2024/08/02 23:06:20 hello,world31
pool exec: 7
2024/08/02 23:06:20 hello,world90
pool exec: 9
pool exec: 3
2024/08/02 23:06:20 hello,world28
pool exec: 2
2024/08/02 23:06:20 hello,world29
pool exec: 1
2024/08/02 23:06:20 hello,world24
2024/08/02 23:06:20 hello,world26
pool exec: 2
2024/08/02 23:06:20 hello,world34
pool exec: 1
2024/08/02 23:06:20 hello,world93
pool exec: 9
2024/08/02 23:06:20 hello,world21
pool exec: 8
2024/08/02 23:06:20 hello,world92
pool exec: 1
2024/08/02 23:06:20 hello,world23
pool exec: 5
2024/08/02 23:06:20 hello,world22
pool exec: 3
2024/08/02 23:06:20 hello,world20
pool exec: 8
2024/08/02 23:06:20 hello,world25
pool exec: 1
2024/08/02 23:06:20 hello,world91
2024/08/02 23:06:20 hello,world89
pool exec: 6
2024/08/02 23:06:20 hello,world88
pool exec: 6
2024/08/02 23:06:20 hello,world66
pool exec: 6
2024/08/02 23:06:20 hello,world87
pool exec: 9
2024/08/02 23:06:20 hello,world27
pool exec: 4
2024/08/02 23:06:20 hello,world73
pool exec: 4
2024/08/02 23:06:20 hello,world18
pool exec: 1
2024/08/02 23:06:20 hello,world72
pool exec: 6
pool exec: 9
2024/08/02 23:06:20 hello,world30
pool exec: 5
pool exec: 0
2024/08/02 23:06:20 hello,world81
pool exec: 7
2024/08/02 23:06:20 hello,world68
pool exec: 2
2024/08/02 23:06:20 hello,world74
2024/08/02 23:06:20 hello,world67
pool exec: 3
pool exec: 0
2024/08/02 23:06:20 hello,world79
2024/08/02 23:06:20 hello,world85
2024/08/02 23:06:20 hello,world19
pool exec: 3
2024/08/02 23:06:20 hello,world86
pool exec: 4
2024/08/02 23:06:20 hello,world71
2024/08/02 23:06:20 hello,world77
pool exec: 3
2024/08/02 23:06:20 hello,world84
pool exec: 0
2024/08/02 23:06:20 hello,world83
pool exec: 8
pool exec: 9
2024/08/02 23:06:20 hello,world78
pool exec: 4
2024/08/02 23:06:20 hello,world69
pool exec: 2
pool exec: 6
2024/08/02 23:06:20 hello,world76
pool exec: 9
pool exec: 4
2024/08/02 23:06:20 hello,world63
pool exec: 9
2024/08/02 23:06:20 hello,world65
pool exec: 8
2024/08/02 23:06:20 hello,world60
pool exec: 4
2024/08/02 23:06:20 hello,world80
pool exec: 7
2024/08/02 23:06:20 hello,world59
pool exec: 4
2024/08/02 23:06:20 hello,world13
pool exec: 9
2024/08/02 23:06:20 hello,world75
2024/08/02 23:06:20 hello,world16
pool exec: 0
2024/08/02 23:06:20 hello,world15
pool exec: 0
2024/08/02 23:06:20 hello,world14
pool exec: 0
2024/08/02 23:06:20 hello,world11
pool exec: 0
2024/08/02 23:06:20 hello,world58
pool exec: 1
2024/08/02 23:06:20 hello,world82
pool exec: 9
pool exec: 5
2024/08/02 23:06:20 hello,world10
pool exec: 9
2024/08/02 23:06:20 hello,world0
pool exec: 7
pool exec: 0
2024/08/02 23:06:20 hello,world8
pool exec: 7
2024/08/02 23:06:20 hello,world7
2024/08/02 23:06:20 hello,world62
pool exec: 9
pool exec: 2
2024/08/02 23:06:20 hello,world9
pool exec: 2
2024/08/02 23:06:20 hello,world2
pool exec: 2
2024/08/02 23:06:20 hello,world4
pool exec: 9
2024/08/02 23:06:20 hello,world3
pool exec: 9
2024/08/02 23:06:20 hello,world100
pool exec: 9
pool exec: 9
pool exec: 9
2024/08/02 23:06:20 hello,world5
pool exec: 9
pool exec: 9
2024/08/02 23:06:20 hello,world1
pool exec: 9
2024/08/02 23:06:20 hello,world64
pool exec: 0
2024/08/02 23:06:20 hello,world61
pool exit 8
2024/08/02 23:06:20 hello,world70
pool exec: 2
pool exit 2
2024/08/02 23:06:20 hello,world17
pool exit 0
2024/08/02 23:06:20 hello,world12
pool exit 4
2024/08/02 23:06:20 hello,world6
pool exit 7
pool exit 3
pool exec: 9
pool exit 9
pool exit 1
pool exec: 5
pool exit 5
pool exit 6
--- PASS: TestPool (1.00s)
PASSProcess finished with the exit code 0
好了,整體代碼介紹完了,希望你能對協(xié)程池有個比較簡單的了解,也可以基于此代碼,豐富一下邏輯
到此這篇關(guān)于golang實現(xiàn)協(xié)程池的方法示例的文章就介紹到這了,更多相關(guān)golang 協(xié)程池內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Golang編程并發(fā)工具庫MapReduce使用實踐
這篇文章主要為大家介紹了Golang并發(fā)工具庫MapReduce的使用實踐,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04
深入學(xué)習(xí)Golang并發(fā)編程必備利器之sync.Cond類型
Go?語言的?sync?包提供了一系列同步原語,其中?sync.Cond?就是其中之一。本文將深入探討?sync.Cond?的實現(xiàn)原理和使用方法,幫助大家更好地理解和應(yīng)用?sync.Cond,需要的可以參考一下2023-05-05
win7下配置GO語言環(huán)境 + eclipse配置GO開發(fā)
這篇文章主要介紹了win7下配置GO語言環(huán)境 + eclipse配置GO開發(fā),需要的朋友可以參考下2014-10-10
Go?數(shù)據(jù)結(jié)構(gòu)之二叉樹詳情
這篇文章主要介紹了?Go?數(shù)據(jù)結(jié)構(gòu)之二叉樹詳情,二叉樹是一種數(shù)據(jù)結(jié)構(gòu),在每個節(jié)點下面最多存在兩個其他節(jié)點。即一個節(jié)點要么連接至一個、兩個節(jié)點或不連接其他節(jié)點,下文基于GO語言展開二叉樹結(jié)構(gòu)詳情,需要的朋友可以參考一下2022-05-05
???????Golang實現(xiàn)RabbitMQ中死信隊列幾種情況
本文主要介紹了???????Golang實現(xiàn)RabbitMQ中死信隊列幾種情況,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03
Go語言服務(wù)器開發(fā)之客戶端向服務(wù)器發(fā)送數(shù)據(jù)并接收返回數(shù)據(jù)的方法
這篇文章主要介紹了Go語言服務(wù)器開發(fā)之客戶端向服務(wù)器發(fā)送數(shù)據(jù)并接收返回數(shù)據(jù)的方法,實例分析了客戶端的開發(fā)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-02-02

