Khi khác nhau, trên bản đồ m
có nhà văn đồng thời, kể cả những người mà có thể xóa khỏi bản đồ, là nó không thread-safe để làm điều này ?:Có nhận được một giá trị sử dụng phạm vi không an toàn chỉ trong Go?
for k, v := range m { ... }
Tôi đang nghĩ là thread-safe tôi cần phải ngăn các nhà văn khác có thể thay đổi giá trị v
trong khi tôi đang đọc nó và (khi sử dụng mutex và vì khóa là một bước riêng), hãy xác minh rằng khóa k
vẫn còn trong bản đồ. Ví dụ:
for k := range m {
m.mutex.RLock()
v, found := m[k]
m.mutex.RUnlock()
if found {
... // process v
}
}
(Giả sử rằng các tác giả khác được ghi khóa m
trước khi thay đổi v
.) Có cách nào tốt hơn?
Chỉnh sửa để thêm: Tôi biết rằng bản đồ không an toàn cho chủ đề. Tuy nhiên, chúng an toàn theo một cách, theo thông số Go tại http://golang.org/ref/spec#For_statements (tìm kiếm "Nếu các mục nhập bản đồ chưa đạt được bị xóa trong khi lặp lại"). Trang này chỉ ra rằng mã sử dụng range
không cần phải lo lắng về các goroutines khác chèn vào hoặc xóa khỏi bản đồ. Câu hỏi của tôi là, sợi chỉ an toàn này có mở rộng đến v
, sao cho tôi có thể nhận được v
để chỉ đọc chỉ sử dụng for k, v := range m
và không có cơ chế an toàn chỉ khác? Tôi đã tạo một số mã thử nghiệm để cố gắng buộc ứng dụng bị lỗi để chứng minh rằng nó không hoạt động, nhưng thậm chí chạy mã blatantly thread-unsafe (rất nhiều goroutines tức giận sửa đổi cùng một giá trị bản đồ mà không có cơ chế khóa tại chỗ). get Go to crash!
Chỉ cần một bình luận (ít hơn cho OP người có thể đã biết điều đó hơn cho độc giả khác): http://golang.org/doc/go_faq.html#atomic_maps –