Ответ 1
Существует множество способов очистки вещей от map
без доступа к карте. Что работает для вашего приложения, зависит от того, что он делает.
0) Просто заблокируйте карту во время работы над ней. Если карта не слишком большая или у вас есть некоторый толерантность к задержкам, она быстро выполняет задание (с точки зрения времени, которое вы тратите на нее), и вы можете переходить к размышлению о других вещах. Если это станет проблемой позже, вы можете вернуться к проблеме.
1) Скопируйте объекты или указатели и очистите карту, удерживая блокировку, затем отпустите объекты в фоновом режиме. Если проблема в том, что медленность освобождения будет удерживать замок долгое время, это простой способ для этого.
2) Если эффективные чтения в основном имеют значение, используйте atomic.Value
. Это позволяет полностью заменить одну карту новой и другой. Если записи составляют, по существу, 0% от вашей рабочей нагрузки, эффективный считывает баланс стоимости создания новой карты при каждом изменении. Это редко, но это происходит, например, encoding/gob
имеет глобальную карту типов, управляемых таким образом.
3) Если ни один из них не делает все, что вам нужно, настройте, как вы храните данные (например, осколочно карту). Замените карту на 16 карт и хеш-ключи самостоятельно, чтобы решить, к какой карте принадлежит вещь, а затем вы можете заблокировать один осколок за раз, для очистки или любой другой записи.
Также существует проблема гонки между выпуском и использованием: goroutine A получает что-то с карты, B очищает карту и освобождает вещь, A использует выпущенную вещь.
Одна стратегия заключается в том, чтобы блокировать каждое значение во время его использования или выпуска; то вам нужны блокировки, но не глобальные.
Другой - терпеть последствия рас, если они известны и не катастрофичны; например, одновременный доступ к net.Conn
явно разрешен его документами, поэтому закрытие подключенного к использованию соединения может привести к ошибке запроса на него, но не приведет к поведению приложения undefined. Вы действительно должны быть уверены, что знаете, в чем вы тогда попадаете, потому что многие доброкачественные расы не являются.
Наконец, возможно, ваше приложение уже гарантирует, что не будут удалены неиспользуемые объекты, например. там безопасно поддерживается отсчет ссылок на объекты и освобождаются только неиспользуемые объекты. Тогда, конечно, вам не о чем волноваться.
Возможно, возникает соблазн попытаться заменить эти блокировки на каналы каким-то образом, но я не вижу никаких преимуществ от этого. Приятно, когда вы можете проектировать свое приложение, думая главным образом о связях между процессами, а не об общих данных, но когда у вас есть общие данные, нет смысла притворяться иначе. Исключение небезопасного доступа к общим данным - это блокировки для.