Как я могу обработать несколько сокетов в демоне Perl с большим использованием памяти? - PullRequest
5 голосов
/ 11 декабря 2008

Я создал клиент-серверную программу на Perl, используя IO :: Socket :: INET. Я получаю доступ к серверу через сайт на основе CGI. Моя серверная программа будет работать как демон и будет принимать несколько одновременных подключений. Мой серверный процесс занимает около 100 МБ памяти (9 больших массивов, много массивов ...). Я хочу, чтобы эти хеши находились в памяти и обменивались ими, чтобы мне не приходилось создавать их для каждого соединения. Создание хэша занимает 10-15 секунд.

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

Родительский процесс создает 9 больших хешей. Для каждого ребенка мне нужно сослаться на один или несколько хэшей в режиме только для чтения. Я не буду обновлять хеши через ребенка. Я хочу использовать что-то вроде копирования при записи, с помощью которого я могу поделиться целыми 100 МБ или целыми глобальными переменными, созданными родителем, со всеми дочерними элементами? или любой другой механизм, такой как темы. Я ожидаю, что сервер получит минимум 100 запросов в секунду, и он сможет обрабатывать их все параллельно. В среднем ребенок выходит через 2 секунды.

Я использую Cygwin в Windows XP только с 1 ГБ ОЗУ. Я не нахожу способа преодолеть эту проблему. Можете ли вы предложить что-то? Как я могу делиться переменными, а также создавать 100 дочерних процессов в секунду, управлять ими и синхронизировать их,

Спасибо.

Ответы [ 3 ]

3 голосов
/ 11 декабря 2008

Вместо разветвления есть два других подхода для обработки одновременных соединений. Либо вы используете темы или подход к опросу.

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

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

Продолжите исследование этих двух вариантов и решите, какой из них подходит вам больше всего.

См. Например: http://www.perlfect.com/articles/select.shtml

2 голосов
/ 11 декабря 2008

Эта архитектура не подходит для Cygwin. Работать на реальных системах Unix дешево, но на поддельных системах Unix, таких как Cygwin, это ужасно дорого, потому что все данные должны быть скопированы (реальные устройства используют копирование при записи). Использование потоков изменяет схему использования памяти (более высокое базовое использование, но меньшее увеличение на поток), но, скорее всего, оно все равно будет неэффективным.

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

2 голосов
/ 11 декабря 2008

Если у вас так много данных, я удивляюсь, почему вы просто не используете базу данных?

...