Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Perl: Общие вопросы > mod_perl и глобальные переменные |
Автор: Ramirez 4.8.2007, 02:00 |
Кто знаком с сабжем, помогите расставить все по местам. mod_perl-скрипты компилируются 1 раз на этапе загрузки веб-сервера (при условии что они грузятся через perlrequire в конфиге апача). значит, если некий пакет создает глобальную переменную при иннициализации, она будет жива от начала запуска апача до его останова. и доступна видимо будет всем процессам апача? эдакий "shared memory" получается? из этого следует, видимо, что если я открою подключение к бд, например, и привяжу его к этой переменной, то оно тоже будет одно, на все процессы апача? Я правильно себе представляю механизм? С мод_перл я, скорее, на "вы", поэтому извиняюсь за сумбурное изложение... Спасибо. |
Автор: djkostya 4.8.2007, 08:08 |
Да с shared memory так и получиться.... Коннект постоянный лучше используйте Apache::DBI |
Автор: Ramirez 6.8.2007, 17:15 | ||||
Я такой фокус пытаюсь с Net::Telnet проделать. И получается, что он все равно плодит подключения на каждый процесс веб сервера. А мне хочется одного на всех добиться. Код примерно такой:
В конфиге апача следующее:
В preload.perl прописано: use MyPack; Собственно, чего я ожидаю: при старте апача компилируется и загружается MyPack, в нем создается переменная $telnet, которая должна быть общая на все копии апача. Потом, при обработке запроса от клиента, вызывается процедура somesub и (при первом вызове) к этой переменой аттачится обьект Net::Telnet. Так как он глобальный, все последующие вызовы (в том числе и от других клиентов, других копий апача) не должны плодить новых коннектов (новых копий Net::Telnet).... а они плодят. Почему? Вообще, проблема к Net::Telnet отношения не имеет, т.к. также ведет себя любая переменная: она всегда пустая при инициализации нового запроса. Т.е. модуль может и компилируется при старте апача, но инициализируется он каждый раз как-бы "с нуля". Видимо это происходит в тот момент когда отпочковывается новая копия апача, хотя больше похоже что вообще на каждый новый запрос. PS: хотя вцелом - вполне логично... апач ведь копированием себя размножается.... поэтому сколько апачей - столько и коннектов =( обкурился уже исходниками Apache::DBI, как оно работает?! обьясните кто нибудь "на пальцах" =) |
Автор: Ramirez 7.8.2007, 12:19 | ||
Вобщем, я заставил его работать так как мне хотелось, но несколько неожиданным способом: в файле preload.perl, который указан в конфиге апача в директиве PerlRequire, сделал так:
и тогда, действительно, подключение создается одно, при старте апача, и оно общее для всех копий апача. Но почему это работает именно так, я что-то не до конца понимаю. Так что вопрос всетаки остается открытым. |
Автор: ginnie 31.3.2008, 11:51 |
Уважаемый Ramirez, дело в том, что созданная Вами глобальная переменная является глобальной для всех процессов только на чтение, если какой-то процесс пишет в нее, то происходит COW (копирование при записи) и новое значение становится глобальным для этого процесса, остальные процессы видят первоначальное значение. В последнем примере, значение глобальной переменной присваивается при компиляции, поэтому оно доступно всем процессам. |
Автор: Ramirez 31.3.2008, 12:08 |
Про копирование при записи я не занл, спасибо! Но непонятен мне несколько другой момент: почему пространство имен скомпилированое при старте внутри мастер-процесса "расшаривается" между потомками, именно расшаривается (может я плохо тестил?) т.е. потомки могут туда и писать и при этом все изменения видны. т.е. копирования не происходит. Это баг или фича? =) Опять-же повторюсь, может я плохо тестил. Сейчас попробую еще ряд экспериментов поставить. |