修改部分描述,添加必要的标点符号,补充代码超链接 (#804)

This commit is contained in:
Jck
2021-10-25 23:34:42 +08:00
committed by GitHub
parent d5578df00a
commit 39dbdb7094
100 changed files with 433 additions and 414 deletions

View File

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