Golang 并发非阻塞缓存

Golang 并发非阻塞缓存,第1张

概述《The Go Programming Language》笔记 import "sync"type Func func(key string) (interface{}, error)type result struct { value interface{} err error}type entry struct { res result rea 《The Go Programming Language》笔记
import "sync"type Func func(key string) (interface{},error)type result struct {    value interface{}    err   error}type entry struct {    res result    ready chan struct{} //closed when res is ready}type MemoryCache struct {    f     Func    mu    sync.Mutex    cache map[string]*entry}func New(f Func) *MemoryCache {    return &MemoryCache{f: f,cache: make(map[string]*entry)}}//获取互斥锁来保护共享变量cache map,查询map中是否存在指定key的value//如果不存在那么分配空间插入新值,释放互斥锁。//如果存在且其值没有写入完即其他goroutine在调用f这个慢函数,//goroutine必须等待值ready之后才能读到key的value//如果没有key对应的value,需要向map中插入一个没有ready的entry,//当前正在调用的goroutine就需要负责调用慢函数更新result以及向其他goroutine//广播(关闭ready)result已经可读了func (mc *MemoryCache) Get(key string) (interface{},error) {    mc.mu.Lock()    e := mc.cache[key]    if e == nil { //e为空        //This is the first request for this key        e = &entry{ready:make(chan struct{})}        mc.cache[key] = e        mc.mu.Unlock()        e.res.value,e.res.err = mc.f(key) //执行耗时函数        close(e.ready)//broadcast ready condition    }else {        mc.mu.Unlock()        <-e.ready //阻塞,直到ready关闭    }    return e.res.value,e.res.err}
type Func func(key string) (interface{},error)type result struct {    value interface{}    err   error}type entry struct {    res   result    ready chan struct{} //closed when res is ready}type request struct {    key      string    response chan<- result}type MemoryCache struct {    requests chan request}func New(f Func) *MemoryCache {    mc := &MemoryCache{requests: make(chan request)}    go mc.server(f)    return mc}func (mc *MemoryCache) Get(key string) (interface{},error) {    response := make(chan result)    mc.requests <- request{key,response}    res := <- response    return res.value,res.err}func (mc *MemoryCache) server(f Func) {    cache := make(map[string]*entry)    for req := range mc.requests {        e := cache[req.key]        if e == nil {            e = &entry{ready: make(chan struct{})}            cache[req.key] = e            go e.call(f,req.key)        }        go e.deliver(req.response)    }}func (mc *MemoryCache) Close()  {    close(mc.requests)}func (e *entry) call(f Func,key string) {    e.res.value,e.res.err = f(key)    close(e.ready)}func (e *entry) deliver(response chan<- result) {    <-e.ready         //wait for the ready condition    response <- e.res //Send the result to the clIEnt}
总结

以上是内存溢出为你收集整理的Golang 并发阻塞缓存全部内容,希望文章能够帮你解决Golang 并发非阻塞缓存所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1281341.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-09
下一篇 2022-06-09

发表评论

登录后才能评论

评论列表(0条)

保存