Как вы экономите память при получении сообщений из очередей POSIX? - PullRequest
1 голос
/ 11 февраля 2011

Как вы экономите память при получении сообщений из очередей POSIX?

Похоже, что при использовании очередей POSIX в многопроцессорной / многопоточной среде не существует поточно-безопасного способа перенести сообщение в буфер, который меньше, чем max_msgsize.

Существуют ли стандартные решения этой проблемы? Или это даже проблема?

Мне хорошо известно, что для этого есть и другие замечательные библиотеки, но я просто хотел включить полностью стандартное решение для пользователей, если они не хотят иметь дело с зависимостями.

К вашему сведению, я пытаюсь поставить в очередь потенциально сотни мегабайт на сообщение, и у меня есть пул процессов с несколькими потоками, каждый из которых освобождает сообщения для обработки.

Спасибо, Chenz

Ответы [ 2 ]

2 голосов
/ 14 февраля 2011

Интерфейс очереди POSIX, как вы заметили, не позволяет запрашивать размер сообщения.

В результате, следовательно, все сообщения могут иметь максимальный размер, настроенный определением очереди,и вы должны предположить, что упрощенная реализация вполне могла бы использовать это для простоты ведения записей.

Учитывая, что вы имеете дело с многомегабайтными сообщениями, как, скажем, вы помещаете эти сообщения в очередь маловероятнобыть хорошим решением (к сожалению).

Если ваша скорость сообщений низкая (до некоторого определения low ) и у вас действительно есть разумная верхняя граница, тогда просто попробуйте и попробуйтеit out.

За исключением этого, вашей следующей лучшей ставкой было бы использовать очередь как очередь рабочих заданий, а не как очередь рабочих элементов.Ваши рабочие элементы должны храниться по-разному, возможно, в файлах.Затем в очереди у вас есть хорошее короткое имя файла, указывающее на расположение рабочего элемента, о котором нужно позаботиться.

Удачи

0 голосов
/ 14 февраля 2011

Я думаю, что нет действительно хорошего способа сделать это. Вот идея, но я думаю, вы обнаружите, что она работает плохо из-за конфликта блокировок:

Один статический буфер равен размеру максимального сообщения. Поскольку имеется общий буфер, теперь процесс удаления из очереди должен выглядеть следующим образом:

  • замок семафора
  • очередь из статического буфера
  • выяснить реальный размер сообщения
  • копировать из статического буфера в локальный буфер потока, который является фактическим размером сообщения
  • разблокировать семафор

Существуют издержки, связанные с наличием статического буфера, но в зависимости от распределения размеров ваших сообщений вы все равно, вероятно, увидите уменьшение общего использования памяти. Однако теперь вам приходится иметь дело с конфликтом за статический буфер, который, вероятно, будет велик, особенно когда несколько больших сообщений приходят подряд. Если очень большие сообщения редки, то это не может быть ужасным решением.

...