使用切片和Golang同步。地图结构

问题描述 投票:0回答:1

为了调试一些并发问题,我正在将部分代码从处理常规Golang映射切换为处理sync.Map。但是,当我尝试运行新代码时,遇到两个不确定的调试错误。

原始代码块:

        sync_mutex.Lock()
        if _, ok := the_map[cur_h]; ok {

            the_map[cur_h] = append(the_map[cur_h], cur_id)

        } else {

            value := []int{cur_id}
            the_map[cur_h] = value

        }
        sync_mutex.Unlock()

新代码块:

if _, ok := sync_map.Load(cur_h); ok {
                sync_mutex.Lock()
                cur_slice, _ := sync_map.Load(cur_h)
                updtd_slice := append(cur_slice, cur_id) // error #1

                sync_map.Store(cur_h, updtd_slice)
                map_mutex.Unlock()

            } else {
                map_mutex.Lock()
                value := []int{cur_id}
                sync_map.Store(cur_h, []int{value}) // error #2
                sync_mutex.Unlock()

            }

引发的错误是:

... first argument to append must be slice; have interface {}
... cannot use value (type []int) as type int in array or slice literal
go concurrency mutex race-condition goroutine
1个回答
0
投票

sync_map.Load返回一个interface{},这就是您遇到第一个错误的原因。您必须使用类型断言来获取基础类型:

cur_slice_i, _ := sync_map.Load(cur_h)
cur_slice := cur_slice_i.([]int)
updtd_slice := append(cur_slice, cur_id) 

不是以上所述,cur_slice_i可以为nil。即使您先检查并加载,如果有人在另一个goroutine中将其从地图中删除,您在这里也可能会得到nil。

第二个错误再次是类型不匹配:值已经是一个int数组,所以:

sync_map.Store(cur_h, value)

您首次将地图与互斥锁一起使用是正确的。如果您在访问该地图的所有其他goroutine中使用相同的模式,则不应遇到与并发访问地图有关的问题。

© www.soinside.com 2019 - 2024. All rights reserved.