Ответ 1
На самом деле есть способ, хотя я сам не реализовал его там на бумаге блокировать свободную карту с помощью указателей опасности от выдающегося эксперта на С++ Андрей Александреску.
Мы разрабатываем сетевое приложение на основе C/S, мы обнаруживаем, что слишком много блокировок, добавляющих к std:: map, что производительность сервера стала плохой.
Интересно, можно ли реализовать карту без блокировки, если да, как? Есть ли там открытый исходный код?
EDIT: Фактически мы используем std:: map для хранения информации о сокетах, мы сделали инкапсуляцию на основе описания файла сокета, чтобы включить в него другую необходимую информацию, такую как ip-адрес, порт, тип сокета, tcp или udp и т.д.
Чтобы обобщить, мы имеем глобальную карту, говорящую, что это
map<int fileDescriptor, socketInfor*> SocketsMap,
то каждый поток, который используется для отправки данных, должен получить доступ к SocketsMap, и им нужно добавить mutex перед чтением из SocketsMap или записи в SocketsMap, поэтому уровень concurrency для всего приложения будет значительно уменьшен из-за того, что многие блокирует добавление к SocketsMap.
Чтобы избежать проблемы уровня concurrency, у нас есть два решения: 1. храните каждый socketInfor * отдельно. 2. используйте какую-то незафиксированную карту.
Я хотел бы найти какую-то незафиксированную карту, потому что изменения кода, требуемые этим решением, намного меньше, чем решение 1.
На самом деле есть способ, хотя я сам не реализовал его там на бумаге блокировать свободную карту с помощью указателей опасности от выдающегося эксперта на С++ Андрей Александреску.
HashMap подойдет? Посмотрите Intel Threading Building Blocks, у них есть интересная параллельная карта. Я не уверен, что он заблокирован, но, надеюсь, вы заинтересованы в хорошей многопоточной производительности, особенно не в блокировке. Также вы можете проверить CityHash lib
EDIT:
На самом деле карта хеша TBB не блокируется
Если вы используете С++ 11, вы можете посмотреть AtomicHashMap facebook/folly
Да, я внедрил заблокированную незафиксированную карту (docs) на С++, используя концепцию "Сплит-упорядоченные списки". Это автоматически расширяющийся контейнер и поддерживает миллионы элементов на 64-битном CAS без проблем ABA. По производительности, это beast (см. Стр. 5). Это было широко протестировано с миллионами случайных операций.
Вы можете реализовать карту, используя оптимистический дизайн или транзакционный память.
Этот подход особенно эффективен, если вероятность двух операций, одновременно обращающихся к карте, а другая - изменение структуры, относительно невелико - и вы не хотите, чтобы накладные расходы блокировались каждый раз.
Однако время от времени происходит столкновение, и вам придется каким-то образом привести его (обычно, возвращаясь к последнему стабильному состоянию и повторяя операции).
Если ваше аппаратное обеспечение поддерживает достаточные атомные операции - это можно легко сделать с помощью Compare and Swap (CAS) - где вы меняете только ссылку (и всякий раз, когда вы меняете карту, вы работаете с копией карты, а не с оригиналом, и устанавливаете ее как основную, только когда вы совершаете фиксацию).
Я удивлен, что никто не упомянул об этом, но Click Cliff внедрил безжизненный hashmap в Java, который, я считаю, можно портировать на С++,