Có rất nhiều cách để bạn có thể dọn dẹp mọi thứ từ map
mà không cần truy cập bản đồ. Những gì làm việc cho ứng dụng của bạn phụ thuộc rất nhiều vào những gì nó đang làm.
0) Chỉ cần khóa bản đồ trong khi bạn làm việc trên đó. Nếu bản đồ không quá lớn, hoặc bạn có dung sai trễ, nó sẽ hoàn thành công việc một cách nhanh chóng (về thời gian bạn chi tiêu cho nó) và bạn có thể tiếp tục suy nghĩ về những thứ khác. Nếu nó trở thành một vấn đề sau này, bạn có thể quay trở lại vấn đề sau đó.
1) Sao chép các đối tượng hoặc con trỏ ra và xóa bản đồ trong khi giữ khóa, sau đó nhả các đối tượng trong nền. Nếu vấn đề là sự chậm phát hành bản thân sẽ giữ cho khóa được giữ trong một thời gian dài, đây là giải pháp đơn giản cho điều đó.
2) Nếu đọc hiệu quả về cơ bản là quan trọng, hãy sử dụng atomic.Value
. Điều đó cho phép bạn thay thế hoàn toàn một bản đồ bằng một bản đồ mới và khác.Nếu viết về cơ bản là 0% khối lượng công việc của bạn, thì hiệu quả đọc sẽ cân bằng chi phí tạo bản đồ mới trên mọi thay đổi. Điều đó hiếm, nhưng điều đó xảy ra, ví dụ: encoding/gob
có bản đồ toàn cầu về các loại được quản lý theo cách này.
3) Nếu không ai trong số đó làm mọi thứ bạn cần, hãy tinh chỉnh cách bạn lưu trữ dữ liệu (ví dụ: phân phát bản đồ). Thay thế bản đồ của bạn bằng 16 bản đồ và các khóa băm để quyết định bản đồ nào thuộc về, và sau đó bạn có thể khóa từng mảnh một, để dọn dẹp hoặc viết khác.
Ngoài ra còn có vấn đề của một cuộc đua giữa phát hành và sử dụng: goroutine A nhận được một cái gì đó từ bản đồ, B xóa bản đồ và phát hành điều, A sử dụng điều phát hành.
Một chiến lược có để khóa từng giá trị trong khi bạn sử dụng hoặc giải phóng nó; thì bạn cần khóa nhưng không cần khóa.
Cách khác là chịu đựng hậu quả của chủng tộc nếu chúng được biết đến và không phải là thảm họa; ví dụ: quyền truy cập đồng thời vào các tài liệu của nó được cho phép một cách rõ ràng, do đó việc đóng kết nối đang sử dụng có thể khiến yêu cầu lỗi nhưng không dẫn đến hành vi ứng dụng chưa xác định. Bạn phải thực sự chắc chắn rằng bạn biết những gì bạn đang nhận được vào sau đó, mặc dù, vì many benign-seeming races aren't.
Cuối cùng, có thể ứng dụng của bạn đã đảm bảo không có đối tượng đang sử dụng nào được giải phóng, ví dụ: có một số tham chiếu được duy trì một cách an toàn trên các đối tượng và chỉ các đối tượng không sử dụng được giải phóng. Sau đó, tất nhiên, bạn không phải lo lắng.
Có thể sẽ cố gắng thay thế các khóa này bằng các kênh bằng cách nào đó nhưng tôi không thấy bất kỳ lợi ích nào từ nó. Đó là đẹp khi bạn có thể thiết kế ứng dụng của mình suy nghĩ chủ yếu về mặt giao tiếp giữa các quy trình thay vì dữ liệu được chia sẻ, nhưng khi bạn có dữ liệu được chia sẻ, không sử dụng trong giả vờ khác. Việc loại trừ quyền truy cập không an toàn vào dữ liệu được chia sẻ là những khóa được sử dụng.
Chúng tôi cần thêm ngữ cảnh để làm việc với điều này. Bản đồ chứa đựng những gì? Nó to lớn? Làm thế nào nhanh chóng được phát hành một điều? (Cái gì _is_ phát hành?) Có phải là một thảm họa nếu một đối tượng được phát hành được sử dụng bởi một goroutine khác, và nếu như vậy, điều gì quyết định một đối tượng được chọn ra khỏi bản đồ được sử dụng trong bao lâu? Ứng dụng là gì và ưu tiên của nó (ví dụ: tối đa hóa thông lượng so với giới hạn thời gian chờ) là gì? – twotwotwo