瀏覽代碼

14.15 The leaky bucket algorithm 漏桶算法 (#632)

* Create 14.15.md

* Update 14.15.md

* Update 14.15.md

* Update 14.15.md

* Update 14.15.md

* Update 14.15.md

* Update 14.15.md

* Update 14.15.md
Respawnz 6 年之前
父節點
當前提交
4459fd0f17
共有 1 個文件被更改,包括 55 次插入0 次删除
  1. 55 0
      eBook/14.15.md

+ 55 - 0
eBook/14.15.md

@@ -0,0 +1,55 @@
+# 14.15 漏桶算法
+
+(译者注:翻译遵照原文,但是对于完全没听过这个算法的人来说比较晦涩,请配合代码片段理解)
+
+考虑以下的客户端-服务器结构:客户端协程执行一个无限循环从某个源头(也许是网络)接收数据;数据读取到`Buffer`类型的缓冲区。为了避免分配过多的缓冲区以及释放缓冲区,它保留了一份空闲缓冲区列表,并且使用一个缓冲通道来表示这个列表:`var freeList = make(chan *Buffer,100)`
+
+这个可重用的缓冲区队列(freeList)与服务器是共享的。 当接收数据时,客户端尝试从`freeList`获取缓冲区; 但如果此时通道为空,则会分配新的缓冲区。 一旦消息被加载后,它将被发送到服务器上的`serverChan`通道:
+
+    var serverChan = make(chan *Buffer)
+
+以下是客户端的算法代码:
+
+```go
+ 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
+        
+    }
+ }
+ 
+```
+服务器的循环则接收每一条来自客户端的消息并处理它,之后尝试将缓冲返回给共享的空闲缓冲区:
+```go
+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`通道的缓冲区会被“丢到地上”由垃圾收集器回收(故名:漏桶算法)
+
+
+## 链接
+
+- [目录](directory.md)
+- 上一节:[并行化大量数据的计算](14.14.md)
+- 下一节:[对Go协程进行基准测试](14.16.md)