14.15 漏桶算法

(译者注:翻译遵照原文,但是对于完全没听过这个算法的人来说比较晦涩,请配合代码片段理解)

考虑以下的客户端-服务器结构:客户端协程执行一个无限循环从某个源头(也许是网络)接收数据;数据读取到Buffer类型的缓冲区。为了避免分配过多的缓冲区以及释放缓冲区,它保留了一份空闲缓冲区列表,并且使用一个缓冲通道来表示这个列表:var freeList = make(chan *Buffer,100)

这个可重用的缓冲区队列(freeList)与服务器是共享的。 当接收数据时,客户端尝试从freeList获取缓冲区; 但如果此时通道为空,则会分配新的缓冲区。 一旦消息被加载后,它将被发送到服务器上的serverChan通道:

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'
        }
    }
}

但是这种方法在freeList通道已满的时候是行不通的,因为无法放入空闲freeList通道的缓冲区会被“丢到地上”由垃圾收集器回收(故名:漏桶算法)

链接

看完两件小事

如果你觉得这篇文章对你挺有启发,我想请你帮我两个小忙:

  1. 关注我们的 GitHub 博客,让我们成为长期关系
  2. 把这篇文章分享给你的朋友 / 交流群,让更多的人看到,一起进步,一起成长!
  3. 关注公众号 「IT平头哥联盟」,公众号后台回复「资源」 免费领取我精心整理的前端进阶资源教程

JS中文网是中国领先的新一代开发者社区和专业的技术媒体,一个帮助开发者成长的社区,目前已经覆盖和服务了超过 300 万开发者,你每天都可以在这里找到技术世界的头条内容。欢迎热爱技术的你一起加入交流与学习,JS中文网的使命是帮助开发者用代码改变世界

results matching ""

    No results matching ""