2016-07-25 31 views
-1

在我的項目,我需要,所以我使用貼圖(全局變量)Golang:多維字符串數組,而不是地圖

var url = make(map[string]string) 

,我偶爾會到錯誤"Concurrent writes"因爲我給你讀一個值作爲一個全局變量在函數中的值(不能分配全局,因爲它給出了一個錯誤的非聲明性語句)。

url["test"] = "http://google.com" 

在PHP中,我可以很容易地通過multidimensioanl數組來做到這一點,並閱讀值。有沒有一種方法可以在Go中使用多維數組或地圖來分配並在函數中讀取它?

任何幫助表示讚賞。

+5

Th錯誤並不是因爲你有一個地圖vs一個數組,這是因爲你有一個數據競賽。您需要保護全局地圖免受併發訪問。 – JimB

+0

你如何調用寫入地圖的函數?一些代碼會有幫助。他們被稱爲goroutines嗎?如果是這樣,看看https://golang.org/pkg/sync/#Mutex – abhink

+0

有什麼辦法來聲明和分配值的全球地圖? – ChrisDave

回答

0

當Go運行時檢測到不同的goroutine對地圖的併發寫入時,會發生Concurrent writes錯誤。這是go1.6增加了一個功能:

https://blog.golang.org/go1.6

運行時增加了重量輕,地圖的同時濫用盡力而爲檢測。與往常一樣,如果一個goroutine正在寫入地圖,則其他goroutine不應該同時讀取或寫入地圖。如果運行時檢測到這種情況,它將打印診斷並使程序崩潰。找出更多關於這個問題的最好方法是在比賽探測器下運行它,這將更可靠地識別比賽並給出更多細節。

可以在全球範圍內初始化地圖 - 見https://play.golang.org/p/AjqtQBGMEM(或以下)的例子。相同的代碼片段顯示瞭如何通過同步機制防止地圖數據競爭 - 在寫入地圖之前使用互斥鎖,鎖定以及事後解鎖。

package main 

import (
    "fmt" 
    "sync" 
) 

var mu sync.Mutex 
var mymap = map[string]string{"hello": "world", "foo": "bar"} 

func main() { 
    demo() 
} 

func demo() { 
    mu.Lock() 
    defer mu.Unlock() 
    mymap["hello"] = "gophers" 
    fmt.Println("hello, ", mymap["hello"]) 
} 

的另一種方式,以避免數據爭是使用大小爲1的信道(非緩衝),類似於在https://tour.golang.org/concurrency/2遊覽例如:提取從信道映射,寫入它,並把它回到頻道。

https://golang.org/doc/articles/race_detector.html有關於數據競賽和Go比賽檢測器的更多信息 - 一種非常有用的工具,用於識別難以跟蹤的併發訪問錯誤。