gpt4 book ai didi

go - 从带有锁的 map 中读取不会通过 channel 返回值

转载 作者:数据小太阳 更新时间:2023-10-29 03:33:08 27 4
gpt4 key购买 nike

我尝试在 golang 中实现一个从 map 读取/写入的锁定版本,但它没有返回所需的结果。

主要包

import (
"sync"
"fmt"
)

var m = map[int]string{}
var lock = sync.RWMutex{}

func StoreUrl(id int, url string) {
for {
lock.Lock()
defer lock.Unlock()

m[id] = url
}
}

func LoadUrl(id int, ch chan string) {
for {
lock.RLock()
defer lock.RUnlock()

r := m[id]
ch <- r
}
}

func main() {
go StoreUrl(125, "www.google.com")

chb := make(chan string)
go LoadUrl(125, chb);

C := <-chb
fmt.Println("Result:", C)
}

输出是:

Result: 

意思是这个值不是通过 channel 返回的,我没有得到。没有锁定/goroutines 它似乎工作正常。我做错了什么?

代码也可以在这里找到:

https://play.golang.org/p/-WmRcMty5B

最佳答案

没有 sleep 或某种 IO 的无限循环总是坏主意。

在您的代码中,如果您在 StoreUrl 的开头放置打印语句,您会发现它永远不会被打印出来,即 go 例程从未启动,go 调用正在设置有关的信息这个新的 go 例程在 go 调度程序的某个运行队列中,但调度程序尚未运行以安排该任务。你如何运行调度程序?做 sleep /IO/ channel 读/写。

另一个问题是你的无限循环正在获取锁并试图再次获取锁,这将导致它死锁。 Defer 仅在函数退出后运行,并且由于无限循环,该函数永远不会退出。

下面是修改后的代码,它使用 sleep 来确保每个执行线程都有时间完成它的工作。

package main

import (
"sync"
"fmt"
"time"
)

var m = map[int]string{}
var lock = sync.RWMutex{}

func StoreUrl(id int, url string) {
for {
lock.Lock()
m[id] = url
lock.Unlock()
time.Sleep(1)
}
}

func LoadUrl(id int, ch chan string) {
for {
lock.RLock()
r := m[id]
lock.RUnlock()
ch <- r

}
}

func main() {
go StoreUrl(125, "www.google.com")
time.Sleep(1)
chb := make(chan string)
go LoadUrl(125, chb);

C := <-chb
fmt.Println("Result:", C)
}

编辑:正如@Jaun 在评论中提到的,您还可以使用runtime.Gosched() 而不是 sleep 。

关于go - 从带有锁的 map 中读取不会通过 channel 返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41582210/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com