Khi bạn sử dụng bản đồ trong một chương trình có quyền truy cập đồng thời, có cần sử dụng mutex trong hàm để đọc giá trị không?Bản đồ có quyền truy cập đồng thời
Trả lời
Nhiều độc giả, không có tác giả là okay:
https://groups.google.com/d/msg/golang-nuts/HpLWnGTp-n8/hyUYmnWJqiQJ
Một nhà văn, không có độc giả là okay. (Maps sẽ không được nhiều tốt khác.)
Nếu không, nếu có ít nhất một nhà văn và ít nhất một hoặc nhiều nhà văn hoặc người đọc, sau đó tất cả độc giả và nhà văn phải sử dụng đồng bộ để truy cập bản đồ . Một mutex hoạt động tốt cho việc này.
Tôi đã trả lời câu hỏi của bạn trong this reddit chủ đề cách đây vài ngày:
Trong Go, bản đồ không được thread-safe. Ngoài ra, dữ liệu yêu cầu khóa ngay cả đối với ví dụ đọc nếu có thể có một goroutine khác là ghi cùng một dữ liệu (đồng thời, tức là).
Đánh giá bằng cách làm rõ trong các nhận xét, rằng cũng sẽ có chức năng setter, câu trả lời cho câu hỏi của bạn là có, bạn sẽ phải bảo vệ đọc bằng mutex; bạn có thể sử dụng RWMutex. Ví dụ, bạn có thể xem source về việc thực hiện cấu trúc dữ liệu bảng (sử dụng bản đồ đằng sau hậu trường) mà tôi đã viết (thực ra là một liên kết trong chuỗi reddit).
thường lãng phí khi sử dụng khóa người đọc đầy đủ dành cho người đọc để truy cập tài nguyên nhanh như bản đồ – rmmh
Bạn có thể giải thích một chút không? Điều gì sẽ phù hợp hơn? –
Ổ khóa RW tốt cho các tài nguyên có nhiều tranh chấp, nhưng chúng có nhiều chi phí hơn một mutex. Bản đồ nhận/bộ là đủ nhanh mà chương trình có khả năng sẽ không có đủ tranh chấp để làm cho khóa phức tạp hơn cho thông lượng tốt hơn so với một mutex đơn giản. – rmmh
Bạn có thể sử dụng concurrent-map để xử lý các cơn đau đồng thời cho bạn.
// Create a new map.
map := cmap.NewConcurrentMap()
// Add item to map, adds "bar" under key "foo"
map.Add("foo", "bar")
// Retrieve item from map.
tmp, ok := map.Get("foo")
// Checks if item exists
if ok == true {
// Map stores items as interface{}, hence we'll have to cast.
bar := tmp.(string)
}
// Removes item under key "foo"
map.Remove("foo")
Những điều như thế này là lý do tại sao tôi không thể coi trọng khái niệm " cần generics. " – Lucretiel
Khái niệm không phải là Go "không cần generics" nhưng "hiện không có cách nào sạch để thực hiện generics, chúng ta cần phải suy nghĩ về điều này một số chi tiết". Ví dụ C++ tạo mã cho tất cả các kiểu kết hợp có thể được sử dụng, làm tăng thời gian biên dịch và kích cỡ thực thi bởi một số lượng không hợp lý. – Alexander
nếu bạn chỉ có một người viết, thì có thể bạn có thể lấy đi bằng cách sử dụng Giá trị nguyên tử. Sau đây là chuyển thể từ https://golang.org/pkg/sync/atomic/#example_Value_readMostly (bản gốc sử dụng ổ khóa để bảo vệ văn bản, để hỗ trợ nhiều tác giả)
type Map map[string]string
var m Value
m.Store(make(Map))
read := func(key string) (val string) { // read from multiple go routines
m1 := m.Load().(Map)
return m1[key]
}
insert := func(key, val string) { // update from one go routine
m1 := m.Load().(Map) // load current value of the data structure
m2 := make(Map) // create a new map
for k, v := range m1 {
m2[k] = v // copy all data from the current object to the new one
}
m2[key] = val // do the update that we need (can delete/add/change)
m.Store(m2) // atomically replace the current object with the new one
// At this point all new readers start working with the new version.
// The old version will be garbage collected once the existing readers
// (if any) are done with it.
}
sync.Map
đã sáp nhập để Tới chủ tính đến tháng 27, năm 2017.
Đây là Bản đồ đồng thời chúng tôi tất cả đã chờ đợi.
Đẹp nhất. Lưu ý rằng loại sync.Map mới được thiết kế cho các bản đồ chỉ chắp thêm (vì lý do này không sử dụng các khóa, có nghĩa là nếu bản đồ của bạn có nhiều khả năng bị hỏng thì rất có thể sẽ làm tốt hơn bản đồ kiểu phân đoạn theo câu trả lời của tôi ở trên). – orcaman
@orcaman, bạn có ý nghĩa gì với các bản đồ chỉ nối thêm? – OmarIlias
@OmarIlias Tôi có nghĩa là các trường hợp bạn chủ yếu đặt giá trị mới (không cần chỉnh sửa hoặc xóa các giá trị hiện có). Xem này: https://github.com/golang/go/issues/20360 – orcaman
Tại sao không đã sử dụng mô hình đồng thời Go thay vào đó, có một ví dụ đơn giản ...
type DataManager struct {
/** This contain connection to know dataStore **/
m_dataStores map[string]DataStore
/** That channel is use to access the dataStores map **/
m_dataStoreChan chan map[string]interface{}
}
func newDataManager() *DataManager {
dataManager := new(DataManager)
dataManager.m_dataStores = make(map[string]DataStore)
dataManager.m_dataStoreChan = make(chan map[string]interface{}, 0)
// Concurrency...
go func() {
for {
select {
case op := <-dataManager.m_dataStoreChan:
if op["op"] == "getDataStore" {
storeId := op["storeId"].(string)
op["store"].(chan DataStore) <- dataManager.m_dataStores[storeId]
} else if op["op"] == "getDataStores" {
stores := make([]DataStore, 0)
for _, store := range dataManager.m_dataStores {
stores = append(stores, store)
}
op["stores"].(chan []DataStore) <- stores
} else if op["op"] == "setDataStore" {
store := op["store"].(DataStore)
dataManager.m_dataStores[store.GetId()] = store
} else if op["op"] == "removeDataStore" {
storeId := op["storeId"].(string)
delete(dataManager.m_dataStores, storeId)
}
}
}
}()
return dataManager
}
/**
* Access Map functions...
*/
func (this *DataManager) getDataStore(id string) DataStore {
arguments := make(map[string]interface{})
arguments["op"] = "getDataStore"
arguments["storeId"] = id
result := make(chan DataStore)
arguments["store"] = result
this.m_dataStoreChan <- arguments
return <-result
}
func (this *DataManager) getDataStores() []DataStore {
arguments := make(map[string]interface{})
arguments["op"] = "getDataStores"
result := make(chan []DataStore)
arguments["stores"] = result
this.m_dataStoreChan <- arguments
return <-result
}
func (this *DataManager) setDataStore(store DataStore) {
arguments := make(map[string]interface{})
arguments["op"] = "setDataStore"
arguments["store"] = store
this.m_dataStoreChan <- arguments
}
func (this *DataManager) removeDataStore(id string) {
arguments := make(map[string]interface{})
arguments["storeId"] = id
arguments["op"] = "removeDataStore"
this.m_dataStoreChan <- arguments
}
- 1. bản đồ java cập nhật đồng thời
- 2. đồng thời truy cập file
- 3. Truy cập tệp PHP và đồng thời
- 4. truy cập biến đồng thời trong c
- 5. Truy cập đồng thời trong SQLite
- 6. File.WriteAllText và truy cập đồng thời
- 7. DNS nào có quyền truy cập API?
- 8. iOS - Truy cập đồng thời vào tài nguyên bộ nhớ
- 9. Tê giác và truy cập đồng thời vào javax.script.ScriptEngine
- 10. Bản đồ mảng và bản đồ băm liên tục trong thời gian truy cập của chúng như thế nào?
- 11. Máy ảnh UIImagePicker và AVCaptureSession truy cập đồng thời
- 12. Quyền truy cập vào sys.dm_db_index_usage_stats
- 13. Truy cập đọc đồng thời trên một mảng int []: Có an toàn không? Có nhanh không?
- 14. Lớp dịch vụ có quyền truy cập vào HttpContext không?
- 15. Bản đồ không đồng nhất
- 16. Truy cập đồng thời vào mảng được chia sẻ có vấn đề trong Node.js
- 17. Đồng bộ hóa quyền truy cập vào đối tượng Immutable Integer
- 18. golang: truy cập nhanh dữ liệu bản đồ trong bản đồ
- 19. Truy cập tên trường bản đồ kết hợp tăng cường
- 20. Truy cập dấu trang bản đồ iphone qua SDK
- 21. Truy cập vào giá trị bản đồ bằng chỉ số
- 22. Quyền thừa kế và quyền truy cập tình bạn. C++
- 23. Bản đồ giao dịch với Bản đồ đồng bộ
- 24. Android systrace có yêu cầu quyền truy cập root không?
- 25. Nhận thông tin phiên bản moodle, không có quyền truy cập quản trị
- 26. Ms Truy cập: Không thể đọc (các) bản ghi; không có quyền đọc trên [bảng]
- 27. Điều khoản IP/bản quyền có lợi cho hợp đồng làm việc tự do hợp đồng
- 28. Github hạn chế quyền truy cập
- 29. Quyền truy cập vùng heap Java
- 30. Quyền truy cập chung vào DbContext
Nếu nó là đúng một chỉ đọc bản đồ, một mutex không cần thiết. – jimt
Tôi không rõ lắm vì sẽ có các chức năng để đặt và nhận các giá trị. –