Удалить модуль Perl из дочернего стека - PullRequest
2 голосов
/ 05 февраля 2012

У меня есть демон, который загружает DBI (DBD :: mysql), а затем разветвляет дочерние процессы.Я бы хотел, чтобы модуль DBI не находился в памяти в разветвленных дочерних процессах.

Так что-то вроде этого:

#!/usr/bin/perl

use DBI;
my $dbh = DBI->connect(db_info);

my $pid = fork();
if($pid){

# The forked process here should not have DBI loaded

}

Спасибо за помощь!

Ответы [ 4 ]

4 голосов
/ 05 февраля 2012

Загрузка модуля означает его выполнение как скрипт. Нет абсолютно никакой разницы между модулем и скриптом для Perl. Чтобы выгрузить модуль, нужно отменить эффекты его запуска. Это не может быть сделано механически, и это невозможно сделать вручную.

Самое простое решение было бы иметь ребенка exec что-то. Это может быть даже сценарий, который вы уже запускаете.

exec($^X, $0, '--child', @args)

Дочернему устройству может быть предоставлен доступ к сокету путем привязки его к дочерним файлам fd 0 (стандартный ввод) и fd 1 (стандартный вывод).

4 голосов
/ 05 февраля 2012

Вы не можете сделать это легко, если не поместите груз после вилки. Но для этого вы не должны использовать use. Сделайте это вместо:

my $pid = fork();
if ($pid) {
     # child
} else {
     require DBI;
     import DBI;
}

Это должно помешать загрузке модуля DBI до момента разветвления. Процедура use, по сути, выполняет требование / импорт, но внутри блока BEGIN {}, поэтому ее не следует использовать.

1 голос
/ 06 февраля 2012

Теперь, зная, что вы хотите с этим делать, поскольку в Perl нет хорошего способа выгрузки модулей, хорошее решение проблемы - написать сервер аутентификации отдельно от сервера приложений. Сервер приложений спрашивает сервер аутентификации, есть ли у IP разрешения. Таким образом, они остаются в совершенно отдельных процессах. Это также может иметь преимущества в плане безопасности: ваш код приложения не может получить доступ к вашей базе данных аутентификации.

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

Это куча дополнительной работы, обслуживания и сложности. Это стоит того, если это вызывает у вас реальные проблемы с памятью, а не только потому, что это вас раздражает. Помните, ОЗУ очень дешево. Время разработки очень дорого.

1 голос
/ 05 февраля 2012

Если вы работаете в современной системе Linux, то форки COW (копирование при записи). Это означает, что страницы из родительского объекта копируются только в адресное пространство дочернего объекта, если они изменены родительским или дочерним объектом. Таким образом, модуль DBI отсутствует в памяти разветвленных дочерних процессов.

Perl 5 не имеет возможности выгрузки модулей из памяти. Если вам действительно нужно, чтобы у детей был какой-то код, отличный от родительского, по какой-то причине вам лучше отделить этот код от основного кода как его собственный сценарий, а затем использовать exec после разветвления для запуска дочерний скрипт. Это будет медленнее, чем обычное разветвление, так как он должен компилировать дочерний код, поэтому, если вы много разветвляетесь, может быть лучше иметь два сценария, которые общаются друг с другом через сокеты и имеют предварительную разветвленность «дочернего» сценария.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...