1. 程式人生 > >golang在多個go routine中進行map或者slice操作應該註意的對象。

golang在多個go routine中進行map或者slice操作應該註意的對象。

切片 產生 light () clas golang get方法 最好 new

因為golang的map和列表切片都是引用類型,且非線程安全的,所以在多個go routine中進行讀寫操作的時候,會產生“map read and map write“的panic錯誤。

某一些類型的對象,會有這種類似的set方法來寫數據,或者get方法來返回一個map:

func (this *object) Set(name, val) {
  this.Lock()
  defer this.Unlock()
  
  this.m[name] = val
}

func (this *object) Get() map[string]string {
  this.Lock()
  defer this.Unlock()

  return this.m
}

  

如果會在多個go routine中通過該對象的Get()方法獲取到的map進行讀操作,並且在其他go routine中用Set()方法來寫操作,那麽有可能會導致“map read and map write“的panic錯誤。

原因是Get方法獲取的map和Set方法操作的map是同一個map,如果讀寫線程在同一時刻操作這2個map,就會產生錯誤。

所以Get方法最好用這種方式返回map:

func (this *object) Get() map[string]string {
    this.Lock()
    defer this.Unlock()

    newm := make(map[string]string)
    for k, v := range this.m {
        newm[k] = v
    }

    return newm
}

這樣每次Get獲取的map,其實是一個新的map,就可以不用考慮同時讀寫的問題了。

golang在多個go routine中進行map或者slice操作應該註意的對象。