golang实现协程池的方法示例
go协程池可以看成一个被初始化的固定大小的协程循环读取函数队列,获取是否有可供调用的函数队列,如果有,则协程池中的一个协程调用并执行该函数,talk is cheap,show me the code。
主体协程池代码如下所示:
package goroutine import ( "context" "fmt" "sync" ) // go实现简单协程池 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(), //自定义自旋锁实现,如果使用go自带的锁,则可能会出现死锁问题 } 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 (www.devze.comp *Pool) Put(fc fn) { p.lock.Lock() p.tasks = append(p.tasks, fc) p.lock.Unlock() }
自定义的自旋锁实现代码如下:
package goroutine import ( "runtime" "sync" "sync/atomic" ) type spinLock uint32 const maxBackoff = 16 func (sl *spinLock) Lockpython() { 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) }
开发环境为goland,运行结果截图如下图:
=== RUN TestPool
pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 0pool exec: 2pool exec: 0pool exec: 1pool exec: 3pool exec: 4pool exec: 7pool exec: 8pool exec: 5pool exec: 6pool exec: 92024/08/02 23:06:20 hello,world97pool exec: 22024/08/02 23:06:20 hello,world42pool exec: 22024/08/02 23:06:20 hello,world57pool exec: 22024/08/02 23:06:20 hello,world56pool exec: 22024/08/02 23:06:20 hello,world55pool exec: 22024/08/02 23:06:20 hello,world54pool exec: 22024/08/02 23:06:20 hello,world53pool exec: 22024/08/02 23:06:20 hello,world52pool exec: 22024/08/02 23:06:20 hello,world51pool exec: 22024/08/02 23:06:20 hello,world50pool exec: 22024/08/02 23:06:20 hello,world49pool exec: 22024/08/02 23:06:20 hello,world48pool exec: 22024/08/02 23:06:20 hello,world47pool exec: 22024/08/02 23:06:20 hello,world46pool exec: 22024/08/02 23:06:20 hello,world45pool exec: 22024/08/02 23:06:20 hello,world44pool exec: 22024/08/02 23:06:20 hello,world95pool exec: 02024/08/02 23:06:20 hello,world43pool exec: 22024/08/02 23:06:20 hello,world41pool exec: 22024/08/02 23:06:20 hello,world40pool exec: 22024/08/02 23:06:20 hello,world33pool exec: 02024/08/02 23:06:20 hello,world39pool exec: 22024/08/02 23:06:20 hello,world38pool exec: 02024/08/02 23:06:20 hello,world372024/08/02 23:06:20 hello,world36pool exec: 2pool exec: 02024/08/02 23:06:20 hello,world96pool exec: 42024/08/02 23:06:20 hello,world982024/08/02 23:06:20 hello,world99pool exec: 32024/08/02 23:06:20 hello,world942024/08/02 23:06:20 hello,world32pool exec: 72024/08/02 23:06:20 hello,world352024/08/02 23:06:20 hello,world31pool exec: 72024/08/02 23:06:20 hello,world90pool exec: 9pool exec: 32024/08/02 23:06:20 hello,world28pool exec: 22024/08/02 23:06:20 hello,world29pool exec: 12024/08/02 23:06:20 hello,world242024/08/02 23:06:20 hello,world26pool exec: 22024/08/02 23:06:20 hello,world34pool exec: 12024/08/02 23javascript:06:20 hello,world93pool exec: 92024/08/02 23:06:20 hello,world21pool exec: 82024/08/02 23:06:20 hello,world92pool exec: 12024/08/02 23:06:20 hello,world23pool exec: 52024/08/02 23:06:20 hello,world22pool exec: 32024/08/02 23:06:20 hello,world20pool exec: 82024/08/02 23:06:20 hello,world25pool exec: 12024/08/02 23:06:20 hello,world912024/08/02 23:06:20 hello,world89pool exec: 62024/08/02 23:06:20 hello,world88pool exec: 62024/0http://www.devze.com8/02 23:06:20 hello,world66pool exec: 62024/08/02 23:06:20 hello,world87pool exec: 92024/08/02 23:06:20 hello,world27pool exec: 42024/08/02 23:06:20 hello,world73pool exec: 42024/08/02 23:06:20 hello,world18pool exec: 12024/08/02 23:06:20 hello,world72pool exec: 6pool exec: 92024/08/02 23:06:20 hello,world30pool exec: 5pool exec: 02024/08/02 23:06:20 hello,world81pool exec: 72024/08/02 23:06:20 hello,world68pool exec: 22024/08/02 23:06:20 hello,world742024/08/02 23:06:20 hello,world67pool exec: 3pool exec: 02024/08/02 23:06:20 hello,world792024/08/02 23:06:20 hello,world852024/08/02 23:06:20 hello,world19pool exec: 32024/08/02 23:06:20 hello,world86pool exec: 42024/08/02 23:06:20 hello,world712024/08/02 23:06:20 hello,world77pool exec: 编程客栈32024/08/02 23:06:20 hello,world84pool exec: 02024/08/02 23:06:20 hello,world83pool exec: 8pool exec: 92024/08/02 23:06:20 hello,world78pool exec: 42024/08/02 23:06:20 hello,world69pool exec: 2pool exec: 62024/08/02 23:06:20 hello,world76pool exec: 9pool exec: 42024/08/02 23:06:20 hello,world63pool exec: 92024/08/02 23:06:20 hello,world65pool exec: 82024/08/02 23:06:20 hello,world60pool exec: 42024/08/02 23:06:20 hello,world80pool exec: 72024/08/02 23:06:20 hello,world59pool exec: 42024/08/02 23:06:20 hello,world13pool exec: 92024/08/02 23:06:20 hello,world752024/08/02 23:06:20 hello,world16pool exec: 02024/08/02 23:06:20 hello,world15pool exec: 02024/08/02 23:06:20 hello,world14pool exec: 02024/08/02 23:06:20 hello,world11pool exec: 02024/08/02 23:06:20 hello,world58pool exec: 12024/08/02 23:06:20 hello,world82pool exec: 9pool exec: 52024/08/02 23:06:20 hello,world10pool exec: 92024/08/02 23:06:20 hello,world0pool exec: 7pool exec: 02024/08/02 23:06:20 hello,world8pool exec: 72024/08/02 23:06:20 hello,world72024/08/02 23:06:20 hello,world62pool exec: 9pool exec: 22024/08/02 23:06:20 hello,world9pool exec: 22024/08/02 23:06:20 hello,world2pool exec: 22024/08/02 23:06:20 hello,world4pool exec: 92024/08/02 23:06:20 hello,world3pool exec: 92024/08/02 23:06:20 hello,world100pool exec: 9pool exec: 9pool exec: 92024/08/02 23:06:20 hello,world5pool exec: 9pool exec: 92024/08/02 23:06:20 hello,world1pool exec: 92024/08/02 23:06:20 hello,world64pool exec: 02024/08/02 23:06:20 hello,world61pool exit 82024/08/02 23:06:20 hello,world70pool exec: 2pool exit 22024/08/02 23:06:20 hello,world17pool exit 02024/08/02 23:06:20 hello,world12pool exit 42024/08/02 23:06:20 hello,world6pool exit 7pool exit 3pool exec: 9pool exit 9pool exit 1pool exec: 5pool exit 5pool exit 6--- PASS: TestPool (1.00s)PASSProcess finished with the exit code 0
好了,整体代码介绍完了,希望你能对协程池有个比较简单的了解,也可以基于此代码,丰富一下逻辑
到此这篇关于golang实现协程池的方法示例的文章就介绍到这了,更多相关golang 协程池内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!
精彩评论