Golang - bufferd channel - pool 池

Pool - 池

1. Story

给大家讲一个昭君创业的小故事:

昭君打算创业,做星际间客运,客户为高端有品格的外星人士

一开始,每来一个外星客户,勤劳的昭君就造一台豪华飞船,执行星际客运,每次执行完客运,飞船到达目的地之后,就地销毁

但是昭君的生意太好,有太多的UFO要造,消耗了大量的钢铁原料,和昭君宝贵的时间精力, 创业的昭君已不堪重荷

此时昭君发现每天的外星人客运量不超过50个,于是他想出了一个好办法,那就是创建一个最高容量为50个飞船的停飞场,不再就地销毁飞船,而是将飞船回收到停飞场,等下一客户要用的时候,就提出来直接使用!

从此昭君只要管理提飞船和回收飞船,只有当停飞场里,一架飞船都没有的时候,才不得不造船

有时候飞船已经被用的破破烂烂的(有时候则是因为有些外星人故意在飞船里拉粑粑),昭君检查飞船不能再投入使用后,就销毁它

有时候停飞场满了,昭君也不得不销毁回收的飞船

本来以为创业即将成功了,谁能想到忽然有人搞起了共享飞船,Shit!昭君的飞船租赁没有了用武之地,创业失败,于是昭君离开了这个让人伤心的地方

结果突然有一天,昭君走在街上被人打了一顿,原来自己当时造的几十架飞船占用了别人的地,导致人家没法开发外星人别野了,昭君连忙回去把剩下的几十架飞船都销毁了

创业真是不易啊

上面这个故事其实就是一个池的使用,池是用于解决 频繁发生的,消耗资源又费时的工作的问题(数据库连接,进程池),在日常的工作中也是经常用到,以下是一个Pool的基本结构,灰色为对应故事中的情节,帮助理解

Golang - bufferd channel - pool 池_第1张图片

2. Code

代码中的方法和属性都可以对应上图找到

package main

// ---------------Worker---------------

type Worker struct {
    IsAvailable bool
}

// 创建
func InitWorker() *Worker {
    return &Worker{}
}

// 执行
func (w *Worker)Process(){

}

// 销毁worker
func (w *Worker)Destory(){
    // 消除之前占用的某一些资源
}

// --------------Pool---------------

type Pool struct {
    availableWorker chan *Worker
}

// 创建Pool
func NewPool(maxsize int)Pool{
    return Pool{
        availableWorker:make(chan *Worker,maxsize), // 限制 bufferd chan 最大缓存数
    }
}

// 获取worker
func (p *Pool) get()(w *Worker){
    select{
    case w = <-p.availableWorker: // 有可用的worker
    default:
        // 无可用的worker,创建(实在没船就创造船)
        w = InitWorker()
    }
    return
}

// 回收worker
func (p *Pool) returnBack(w *Worker){
    // worker 是否还可用(飞船是否还可用)
    if !w.IsAvailable {
        // 不可用,销毁丢弃
        w.Destory()
        return
    }
    select {
    case p.availableWorker<-w: // 如果有位置,则缓存(停飞船喽)
    default:
        // 没位置,销毁丢弃
        w.Destory()
    }
}

// 销毁所有worker(不要重复昭君的惨剧)
func (p *Pool) destroyAllWorker(){
    for {
        select{
        case w:= <-p.availableWorker:
            w.Destory()
        default:
            return
        }
    }
}

// -------------- Let's go -----------------

func main() {
    pool := NewPool(50) // 最大缓存50个worker(50个飞船的停飞场)
    defer pool.destroyAllWorker() // 如果不想被追到街上打的话,最后记得销毁所有的工作者

    for {
        worker := pool.get() // 获取worker
        worker.Process() // 使用worker
        pool.returnBack(worker) // 归还worker
    }

    // 友情提示:该代码接近伪码,不知直接运行
}

你可能感兴趣的:(golang)