golang并发----缓冲通道实现对象池

zjtriplehhh · · 768 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

缓冲通道实现可复用的对象池

type reusableobj struct{}

type objpool struct {
    bufchan chan *reusableobj
}

func newobjpool(numofobj int) *objpool {
    objpool := objpool{}
    objpool.bufchan = make(chan *reusableobj, numofobj)
    for i := 0; i < numofobj; i++ {
        objpool.bufchan <- &reusableobj{}
    }
    return &objpool
}

func (p *objpool) getobj(timeout time.Duration) (*reusableobj, error) {
    select {
    case ret := <-p.bufchan:
        return ret, nil
    case <-time.After(timeout):
        return nil, errors.New("time out")
    }
}

func (p *objpool) releaseobj(obj *reusableobj) error {
    select {
    case p.bufchan <- obj:
        return nil
    // 放不进去了就会返回overflow
    default:
        return errors.New("overflow")
    }
}

func main() {
    pool := newobjpool(10)
    // if err := pool.releaseobj(&reusableobj{}); err != nil {
    //  fmt.Println(err)
    // }
    for i := 0; i < 11; i++ {
        if v, err := pool.getobj(time.Second); err != nil {
            fmt.Println(err)
        } else {
            fmt.Println(v)
            if err := pool.releaseobj(v); err != nil {
                fmt.Println(err)
            }
        }
    }
    fmt.Println("done.")
}

缓冲通道实现一个可复用缓存队列

客户端协程执行一个无限循环从某个源头接收数据,数据读取到Buffer类型的缓冲区。为了避免分配过多的缓冲区以及释放缓冲区,它保留了一份空闲缓冲区列表。

// 可重用的缓冲区队列(freeList)与服务器是共享的
// 当接收数据时,客户端尝试从freeList获取缓冲区
// 但如果此时通道为空,则会分配新的缓冲区。
var freeList = make(chan *Buffer, 100)
var serverChan = make(chan *Buffer)

func client() {
    for {
        var b *Buffer
        // Grab a buffer if available; allocate if not
        select {
        case b = <-freeList:
            // Got one; nothing more to do
        default:
            // None free, so allocate a new one
            b = new(Buffer)
        }
        loadInto(b)     // Read next message from the network
        serverChan <- b // Send to server

    }
}

func server() {
    for {
        b := <-serverChan // Wait for work.
        process(b)
        // Reuse buffer if there's room.
        select {
        case freeList <- b:
            // Reuse buffer if free slot on freeList; nothing more to do
        default:
            // Free list full, just carry on: the buffer is 'dropped'
        }
    }
}

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:zjtriplehhh

查看原文:golang并发----缓冲通道实现对象池

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

768 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传