- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
这是我的并发缓存代码:
package cache
import (
"sync"
)
// Func represents a memoizable function, operating on a string key, to use with a Cache
type Func func(key string) (interface{}, error)
// FuncResult stores the value of a Func call
type FuncResult struct {
val interface{}
err error
}
// Cache is a cache that memoizes results of an expensive computation
//
// It has a traditional implementation using mutexes.
type Cache struct {
// guards done
mu sync.RWMutex
done map[string]chan bool
memo map[string]*FuncResult
f Func
}
// New creates a new Cache and returns its pointer
func New(f Func) *Cache {
return &Cache{
memo: make(map[string]*FuncResult),
done: make(map[string]chan bool),
f: f,
}
}
// Get a string key if it exists, otherwise computes the value and caches it.
//
// Returns the value and whether or not the key existed.
func (c *Cache) Get(key string) (*FuncResult, bool) {
c.mu.RLock()
_, ok := c.done[key]
c.mu.RUnlock()
if ok {
return c.get(key), true
}
c.mu.Lock()
_, ok = c.done[key]
if ok {
c.mu.Unlock()
} else {
c.done[key] = make(chan bool)
c.mu.Unlock()
v, err := c.f(key)
c.memo[key] = &FuncResult{v, err}
close(c.done[key])
}
return c.get(key), ok
}
// get returns the value of key, blocking on an existing computation
func (c *Cache) get(key string) *FuncResult {
<-c.done[key]
fresult, _ := c.memo[key]
return fresult
}
当我用竞争检测器运行这个程序时,我没有得到任何错误:
package main
import (
"fmt"
"log"
"sync"
"time"
"github.com/yangmillstheory/go-cache/cache"
)
var f = func(key string) (interface{}, error) {
log.Printf("Computing value for key %s\n", key)
time.Sleep(1000 * time.Millisecond)
return fmt.Sprintf("value for %s", key), nil
}
func main() {
var wg sync.WaitGroup
c := cache.New(f)
n := 10
k := "key1"
start := time.Now()
for i := 0; i < n; i++ {
wg.Add(1)
go func() {
defer wg.Done()
c.Get(k)
}()
}
wg.Wait()
log.Printf("Elapsed: %s\n", time.Since(start))
}
但是,当我在循环体内启动两个 不同的 goroutine 时,每个 goroutine 都获得不同的键,我得到一个错误:
解决这个问题的方法是添加另一个互斥锁c.nu
来保护memo
,但是它会让程序变慢一点,也更复杂
func (c *Cache) Get(key string) (*FuncResult, bool) {
c.mu.RLock()
_, ok := c.done[key]
c.mu.RUnlock()
if ok {
return c.get(key), true
}
c.mu.Lock()
_, ok = c.done[key]
if ok {
c.mu.Unlock()
} else {
c.done[key] = make(chan bool)
c.mu.Unlock()
v, err := c.f(key)
c.nu.Lock()
c.memo[key] = &FuncResult{v, err}
c.nu.Unlock()
close(c.done[key])
}
return c.get(key), ok
}
// get returns the value of key, blocking on an existing computation
func (c *Cache) get(key string) *FuncResult {
<-c.done[key]
c.nu.RLock()
fresult, _ := c.memo[key]
c.nu.RUnlock()
return fresult
}
这里真的有竞争条件需要担心吗?如果不同的 goroutines 同时访问同一数据结构中的不同键,只要同步发生在对给定键的访问中,这似乎不是问题?
换句话说,您是必须跨所有 key 同步,还是只跨同一个 key 同步?并发备忘录的用例似乎表明后者就足够了?
最佳答案
map 需要同步,尤其是你can not read it while writing to it ,无论它是相同的还是不同的键,因此您需要锁定菜单映射。
关于围棋检测器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50225601/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
我正在对新标签进行一些试验,并且已经遇到了第一个障碍。我想我应该通过实现经典棋盘游戏 Go/Baduk/Weiqi 的一个版本来开始尝试。 我使用 moveTo() 和 lineTo() 绘制了 xy
我注意到标准 Go 库 (Y0) 中定义了用于一阶、二阶和 N 阶贝塞尔函数(Y0、Y1、Yn)的函数。我似乎无法确定这些数学函数的实际应用会使它们变得如此重要以至于包含在标准库中。 有人能帮帮我吗?
我对 kubernetes 的 golang API 有一些疑问。 我应该使用哪一个? k8s.io/client-go 还是 k8s.io/kubernetes/pkg/client?有什么区别?
我正在处理需要 big.Float 类型的数字,我需要将它们分开。我知道 big.Int 有一个 .Div() 函数,但如果我是正确的,那会截断值并失去我使用 big.Float. 相关代码 func
http://golang.org/pkg/sort/ 这是来自 Go 的例子。 // OrderedBy returns a Sorter that sorts using the less fu
我正在尝试使用两种或多种编程语言实现一个带有 float 的程序。该程序确实说了 50k 次迭代,最终将误差降低到非常小的值。 为确保我的结果具有可比性,我想确保在不同语言中使用相同精度的数据类型。请
http://play.golang.org/p/xjs-jwMsr7 我有这个功能 func (e *MyError) Error() string { return fmt.Sprint
code : type ByteSlice []byte func (p *ByteSlice) Append(data []byte) { slice := *p slice = appen
我一直在 Node 和 Go 中尝试使用 WebSockets 和 HTTP/2 库。我的基本设置是创建客户端和服务器,从服务器重复发送文件并测量时间,直到每个文件在客户端可用。 令我惊讶的是,HTT
我是一名优秀的程序员,十分优秀!