在查看一些golang代码时,我发现了以下内容:
ch := make(chan int)
Run Code Online (Sandbox Code Playgroud)
我在golang Chanels的在线教程中查了解:
https://tour.golang.org/concurrency/2
但我觉得这个例子不清楚.
有人可以给我一个简单的解释和使用频道的例子吗?
最近我参加了几次围棋面试.第一个问我How is channel implemented?,然后第二个问我How is goroutine implemented?.你可以猜到,下一个问道How is a Go interface implemented?.
我一直在使用Go六个月,但说实话,我从来没有关心或知道这些Go internals.
我试着通过阅读Go的源代码来学习这些,但却无法真正理解这些精髓.
所以问题是,对于Go中的菜鸟,我如何学习Go internals?
我正在使用以下功能下载小于20MB的文件.它将整个内容读取到内存中,因为另一个函数必须在将字节写入磁盘之前对字节执行操作.
func getURL(url string) ([]byte, error) {
resp, err := http.Get(url)
if err != nil {
return nil, fmt.Errorf("getURL: %s", err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("getURL: %s", err)
}
return body, nil
}
Run Code Online (Sandbox Code Playgroud)
这样可以正常工作,但系统会消耗所有内存.
是否可以释放body由其他函数处理后使用的内存,因此内存使用量不会大于当前正在处理的字节数?
我读了sync.Pool设计,但发现有两种逻辑,为什么我们需要localPool来解决锁竞争。我们可以使用chan来实现一个。
使用频道的速度是的4倍sync.pool!
除了池可以清除对象外,它还有什么优势?
这是池实现和基准测试代码:
package client
import (
"runtime"
"sync"
"testing"
)
type MPool chan interface{}
type A struct {
s string
b int
overflow *[2]*[]*string
}
var p = sync.Pool{
New: func() interface{} { return new(A) },
}
var mp MPool = make(chan interface{}, 100)
func get() interface{} {
select {
case r := <-mp:
return r
default:
return new(A)
}
}
func put(a interface{}) {
select {
case mp <- a:
default:
}
return …Run Code Online (Sandbox Code Playgroud)