Тысячи блокировок чтения / записи в одном процессе

В настоящее время я разрабатываю кроссплатформенное серверное приложение C ++ (Linux / Windows) с крупномасштабным шаблоном синхронизации. Я внутренне использую boost :: thread как абстракцию специфичных для ОС потоков. Моя проблема - защитить массив данных, каждый элемент массива защищен независимой блокировкой чтения / записи .

Мой массив содержит 4096 элементов . Учитывая решение проблемы «читатели-писатели с приоритетом писателя», которое представлено в « Маленькой книге семафоров » (стр. 85), моему приложению потребуется 5 семафоров на элемент массива. Это дает в общей сложности около 20000 семафоров (или, что эквивалентно, 20000 мьютексов + 20000 условных переменных).

Дополнительная специфика моего приложения заключается в том, что в данный момент времени большинство семафоров неактивны (обычно имеется около 32 "клиентов") потоки, ожидающие / сигнализирующие о тысячах семафоров). Обратите внимание, что, поскольку весь сервер работает в одном процессе, я использую облегченные семафоры на основе потоков ( не семафоры между процессами).

У меня двоякий вопрос:

  1. Рекомендуется ли создавать общий из 20000 семафоров в Linux и Windows для одного процесса? Ну, конечно, я думаю, что это не так ...

  2. Если эта практика не рекомендуется, какой метод я могу использовать для уменьшения количества фактических семафоров, например создать набор из N «эмулированных семафоров» поверх 1 фактического семафора ? Я полагаю, что это было бы интересным решением, потому что большинство моих семафоров неактивны в данный момент.

Заранее спасибо!

Сводка полученных ответов

  1. Использование тысяч семафоров не рекомендуется , особенно с точки зрения кроссплатформенности. И поэтому, даже если они не являются семафорами между процессами (они все еще используют дескрипторы под Windows).
  2. Прямой способ решить мою проблему - разбить мой массив, например, на 64 подмассива из 16 элементов, и связать каждый из этих подмассивов с одной блокировкой чтения / записи . К сожалению, это вызывает много споров (1 писатель блокирует чтение до 15 элементов).
  3. Изучив исходный код Boost, я обнаружил, что:

    • Реализация «boost :: mutex» не переносит объекты CRITICAL_SECTION в Windows (но CreateEvent и ReadWriteBarrier),
    • "boost :: shared_mutex" использует CreateSemaphore под Windows (которые являются тяжелыми, межпроцессными объектами), а
    • "boost :: shared_mutex" не оборачивает "pthread_rwlock_t" под Linux.

    . Причины этого мне не кажутся ясными. В частности, использование межпроцессных объектов для "boost :: shared_mutex" под Windows кажется мне неоптимальным.

Сводка открытых вопросов на данный момент

  1. Как я могу создать набор из N "эмулированных семафоров" на вершина 1 фактического семафора, сохраняя конкуренцию между эмулируемыми семафорами как можно меньше?
  2. Как соотносятся «boost :: mutex» и «boost :: shared_mutex» с их родными аналогами (CRITICAL_SECTION и pthread_rwlock_t)?

]

6
задан Tisys 7 August 2011 в 08:38
поделиться