读写结构体数据数据互斥访问问题

guichun68 · 2019-02-27 11:56:21 · 908 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2019-02-27 11:56:21 的主题,其中的信息可能已经有所发展或是发生改变。

一个结构体中如果有map类型的属性时,为保证读写时的互斥添加RWMutex了,但读出时因为等待问题出现了取不到数据(打印-1)情况,请问如何解决,代码如下:

type UserAges struct {
    ages map[string]int
    sync.RWMutex
}

func (ua *UserAges) Add(name string, age int) {
    ua.Lock()
    defer ua.Unlock()
    ua.ages[name] = age
}

func (ua *UserAges) Get(name string) int {
    ua.RLock()
    defer ua.RUnlock()
    if age, ok := ua.ages[name]; ok {
        return age
    }
    return -1
}

func main() {
    ua := &UserAges{ages: make(map[string]int)}
    for i := 0; i < 10; i++ {
        go func(i int) {
            ua.Add("xiaohong"+fmt.Sprintf("%d", i), i)
        }(i)
    }
    for i := 0; i < 10; i++ {
        go func(i int) {
            fmt.Println(ua.Get("xiaohong" + fmt.Sprintf("%d", i)))
        }(i)
    }
    <-time.After(time.Second * 2)
}

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

908 次点击  
加入收藏 微博
6 回复  |  直到 2019-02-27 17:26:54
didadi
didadi · #1 · 6年之前

你添加的时候用的goroutine,读的时候也用的goroutine,你根本没有等他全部写进去再去读,所以读的时候偶尔有几个-1。简单来说,你没有等他写完就去读了,所以没读到。

guichun68
guichun68 · #2 · 6年之前
didadididadi #1 回复

你添加的时候用的goroutine,读的时候也用的goroutine,你根本没有等他全部写进去再去读,所以读的时候偶尔有几个-1。简单来说,你没有等他写完就去读了,所以没读到。

那该如何解决呢,我加了个无缓冲的通道,在Add函数的defer中给通道追加了1,然后在读数据的for循环中从通道取出数据,成功取出则查询之,怎么还是读到-1呢。

didadi
didadi · #3 · 6年之前

waitgroup 。等add goroutine 全部执行完之后,再去读

guichun68
guichun68 · #4 · 6年之前
didadididadi #3 回复

waitgroup 。等add goroutine 全部执行完之后,再去读

add全部执行完再读?意思是说不方便在Add一条数据后的间隙去读取数据了,只能等所有Add做完后才能读?

didadi
didadi · #5 · 6年之前

你的add 不是顺序执行的,你可能先add 的5,但是你读取的时候,读的是4,你能读到吗?好好理解一下并发

guichun68
guichun68 · #6 · 6年之前
didadididadi #5 回复

你的add 不是顺序执行的,你可能先add 的5,但是你读取的时候,读的是4,你能读到吗?好好理解一下并发

哦哦,明白了,谢谢指点!

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传