У меня есть следующие настройки: веб-страница генерирует запросы на изображения, которые отображаются на сервере, реализованном в C ++. Объект, генерирующий изображения, очень дорогостоящий для инициализации, поэтому он сохраняется в 3-4 экземплярах на сервере.
Обычно одновременно поступает около 10 запросов на изображения, поэтому копии объекта необходимо заблокировать.
Проблема заключается в том, что объекты должны быть заблокированы на довольно длительный период ~ 0,5-1,0 секунды, пока изображение не будет завершено. В настоящее время делается массив блокировок для каждой копии объекта, а запросы изображений назначаются конкретной копии случайным образом.
Сравнительный анализ с Mutrace показывает наличие блокировок:
mutrace: общее время выполнения составляет 127612,949 мс.
mutrace: показаны 10 наиболее спорных мьютексов:
+-----------------------------------------------------------------------------------+
| Mutex# Locked Changed Cont. tot.Time[ms] avg.Time[ms] max.Time[ms] Flags |
+-----------------------------------------------------------------------------------+
| 65027 5129457 387745 79148 754.146 0.000 8.045 M-.--. |
| 443324 754545 172260 25960 7984.958 0.011 43.426 Mx.--. |
| 20645 1728872 5531 412 579.019 0.000 5.091 M-.--. |
| 540024 453 406 280 50068.601 110.527 830.096 M-.--. |
| 539797 462 413 254 39928.156 86.425 834.889 M-.--. |
| 540460 475 419 244 34194.536 71.988 698.798 M-.--. |
| 299764 3036 2091 215 149.902 0.049 11.128 Mx.--. |
| 491395 108 94 87 545.591 5.052 58.174 M-.--. |
| 518584 41440 1744 79 367.372 0.009 6.292 M-.--. |
| 487295 48304 5491 69 250.457 0.005 64.186 M-.--. |
+-----------------------------------------------------------------------------------+
В основном замки 539797,539797,540460 довольны все время. Я имею в виду использование единой очереди без блокировки для одного производителя / одного потребителя для каждого объекта, генерирующего изображения, вот примерно псевдокод:
Всякий раз, когда запрос изображения приходит на сервер, обратный вызов вызывается с некоторыми параметрами изображения:
function serverCallBack(params imageParams) {
queueId = imageParams.getQueueId()
queues[queueId].put(imageParams)
result = getImage()
return image
}
Я застрял в том, что нам нужен способ получить результирующее изображение, когда объект закончил рендеринг. Любые идеи о том, как реализовать этот?
Понятно, что если запросов больше, чем объектов, то некоторые запросы будут заблокированы. Вопрос в том, можно ли блокировать более эффективно, чем с мьютексами?
Задача ещё не решена.
Других решений пока нет …