1. 首页
  2. 主题
  3. Go问与答

map的值是指针,修改的指针的值是否线程安全

wu0407 · · 1435 次点击
简单来说,结构体里的字段是map类型,map的值类型是个指针,一个goroutine线程修改指针的值,另一个goroutine读取这个值,是否线程安全?如果不是,大神们有什么建议,怎么修改 场景是这样的,一个goroutine线程会执行 `CreateHealthCheck`,添加一个`status`到`ApiserverHealth`并会启动一个goroutine来修改`readinessProbe`的`ready`字段。另一个goroutine会`GetStatus`查询状态。 ``` type ApiserverHealth struct { manager *Manager status map[int64]*readinessProbe stopCh <-chan struct{} statusLock sync.RWMutex } type readinessProbe struct { ready bool stopCh <-chan struct{} client *resty.Client serverURL string } // 每个id的status会启动一个goroutine来执行修改ready字段 func (r *readinessProbe) start() { probeFunc := func() { resp, err := r.client.R().Get(r.serverURL) if err != nil { // lock ? r.ready = false ginfw.ConsoleLogger.Debugf("failed to probe apiserver %s, %v", r.serverURL, err) } r.ready = true } // 无限循环执行probeFunc,直到r.stopCh关闭 wait.BackoffUntil(probeFunc, wait.NewExponentialBackoffManager(800*time.Millisecond, 30*time.Second, 2*time.Minute, 2.0, 1.0, &clock.RealClock{}), true, r.stopCh) } // 另一个线程添加status func (c *ApiserverHealth) CreateHealthCheck(id int64) { stopCh := make(chan struct{}) probe := &readinessProbe{ stopCh: stopCh, client: resty.New(), serverURL: probePath, } c.setStatus(id, probe) go probe.start() } func (c *ApiserverHealth) setStatus(id int64, probe *readinessProbe) { c.statusLock.Lock() defer c.statusLock.Unlock() c.status[id] = probe } // 另一个线程会执行这份 func (c *ApiserverHealth) GetStatus(id int64) bool { c.statusLock.RLock() defer c.statusLock.RUnlock() return c.status[id].ready } ```
map 不是线程安全的,并非写 map 就直接挂了 需要并发的话用 sync 里面的 map ``` // Map is like a Go map[interface{}]interface{} but is safe for concurrent use // by multiple goroutines without additional locking or coordination. // Loads, stores, and deletes run in amortized constant time. ```
#1
更多评论
这个我知道,所以加了锁,我问题是修改map值的指针指向的值,并不是修改map里的值
#2
不安全 撇开无关信息,两个goroutine读写同一个变量,必然不安全。 可以考虑 sync/atomic包 可以用对应的LoadInt32和StoreInt32取代bool值
#3

用户登录

没有账号?注册

今日阅读排行

    加载中

一周阅读排行

    加载中