ants源码解析(GO)

1,662 阅读2分钟

用来管理goroutine的工具,执行一个task就调度一个worker来运行,然后对worker进行管理,一个worker也相当于一个goroutine.


ants用一个pool管理worker,负责worker的调度还有回收

type Pool struct {	// capacity of the pool.	capacity int32	// running is the number of the currently running goroutines.	running int32	// expiryDuration set the expired time (second) of every worker.	expiryDuration time.Duration	// workers is a slice that store the available workers.	workers []*goWorker	// release is used to notice the pool to closed itself.	release int32	// lock for synchronous operation.	lock sync.Mutex	// cond for waiting to get a idle worker.	cond *sync.Cond	// once makes sure releasing this pool will just be done for one time.	once sync.Once	// workerCache speeds up the obtainment of the an usable worker in function:retrieveWorker.	workerCache sync.Pool	// panicHandler is used to handle panics from each worker goroutine.	// if nil, panics will be thrown out again from worker goroutines.	panicHandler func(interface{})	// Max number of goroutine blocking on pool.Submit.	// 0 (default value) means no such limit.	maxBlockingTasks int32	// goroutine already been blocked on pool.Submit	// protected by pool.lock	blockingNum int32	// When nonblocking is true, Pool.Submit will never be blocked.	// ErrPoolOverload will be returned when Pool.Submit cannot be done at once.	// When nonblocking is true, MaxBlockingTasks is inoperative.	nonblocking bool}type goWorker struct {	// pool who owns this worker.	pool *Pool	// task is a job should be done.	task chan func()	// recycleTime will be update when putting a worker back into queue.	recycleTime time.Time}




从pool中获取一个可用worker

pool -> retrieveWorker():
判断p.workers是否有闲置的worker可以取,有的话,从最后取出一个worker.
若p.workers没有闲置的worker可以取,则判断运行中的worker是否达到上限, 若没有,从p.workerCache取出一个woker,若p.workerCache没有就新建一个worker.
若运行中的worker达到上限,且是不阻塞的pool则直接返回nil.
若运行中的worker达到上限,且是阻塞的pool,则再阻塞数量没超过限定的数量时,p.blockingNum++并等待信号.
接收到信号的时候p.blockingNum—,判断p.workers中是否有可以运行的worker,有则返回worker,若没有则重新阻塞.



释放pool里的worker

pool -> Release():

只执行一次
p.release置1
所有worker都传nil task



调整pool中worker数量:

tune(size uint)


除了pool,worker.但确认执行的task中的func都是一样时,可用pool_func,worker_func.其中传递不是task了,而是task执行的参数.worker获取到参数,就塞进默认的func来执行.