保证并发安全,实现如下接口
type sp interface {
Out(key string, val interface{}) //存入key /val,如果该key读取的goroutine挂起,则唤醒。此方法不会阻塞,时刻都可以立即执行并返回
Rd(key string, timeout time.Duration) interface{} //读取一个key,如果key不存在阻塞,等待key存在或者超时
}
保证并发安全,实现如下接口
type sp interface {
Out(key string, val interface{}) //存入key /val,如果该key读取的goroutine挂起,则唤醒。此方法不会阻塞,时刻都可以立即执行并返回
Rd(key string, timeout time.Duration) interface{} //读取一个key,如果key不存在阻塞,等待key存在或者超时
}
写了一段代码,不知道是否符合你的要求:
func main() {
m := make(map[string]int)
keyChan := make(chan string)
valChan := make(chan int)
var wg sync.WaitGroup
var l sync.RWMutex
done := make(chan struct{})
for i := 0; i < 3; i++ {
go func(i int) {
key := "test" + strconv.Itoa(i)
l.RLock()
v, ok := m[key]
l.RUnlock()
if !ok {
wg.Add(1)
go func() {
keyChan <- key
defer wg.Done()
timeout := time.After(10 * time.Second)
select {
case <-timeout:
log.Panic("wait too long!")
case v := <-valChan:
log.Printf("val is %d\n", v)
}
}()
wg.Wait()
} else {
log.Printf("val is %d\n", v)
}
done <- struct{}{}
}(i)
}
go func() {
rand.Seed(time.Now().Unix())
for {
select {
case k := <-keyChan:
time.Sleep(2 * time.Second)
l.Lock()
v := rand.Intn(100)
m[k] = v
l.Unlock()
valChan <- v
default:
}
}
}()
select {}
}
7 回答5.3k 阅读
6 回答6.8k 阅读✓ 已解决
4 回答2.3k 阅读
1 回答3.3k 阅读
2 回答893 阅读✓ 已解决
2 回答2.2k 阅读
1 回答2.1k 阅读
可以利用
channel
关闭goroutine
不阻塞特性来实现:下面的代码可以实现你的需求,只是没有写key被多次写入的判断逻辑。