为了账号安全,请及时绑定邮箱和手机立即绑定

为什么即使有锁,GO 也会因“并发映射写入”而恐慌?

为什么即使有锁,GO 也会因“并发映射写入”而恐慌?

Go
12345678_0001 2023-04-24 16:03:04
当尝试将此结构与多个 goroutine 一起使用时,有时我会遇到以下错误之一:fatal error: concurrent map read and map write或者concurrent map writes阅读此线程后,我确保在构造函数中返回一个引用并将引用传递给接收者。使用它的全部代码都在这个 github repo中type concurrentStorage struct {    sync.Mutex    domain string    urls map[url.URL]bool}func newConcurrentStorage(d string) *concurrentStorage{    return &concurrentStorage{        domain: d,        urls: map[url.URL]bool{},    }}func (c *concurrentStorage) add(u url.URL) (bool) {    c.Lock()    defer c.Unlock()    if _, ok := c.urls[u]; ok{        return false    }    c.urls[u] = true    return true}
查看完整描述

1 回答

?
翻翻过去那场雪

TA贡献2065条经验 获得超13个赞

在阅读您链接到的 Github 上的代码后,该crawl()函数接受一个concurrentStorage(不是指针)。

*urlSet对于调用 时的每个取消引用(即:)crawl(),您正在复制concurrentStorage结构(包括sync.Mutex),而地图保留指向原始结构的指针。这意味着您的互斥体与每个 goroutine 是隔离的,同时它们共享相同的状态。

如果您更改crawl()为接受指针,并停止取消引用concurrentStorage,它将按您的预期工作。


查看完整回答
反对 回复 2023-04-24
  • 1 回答
  • 0 关注
  • 90 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信