Отказ от ответственности
Прежде всего, я знаю, что этот вопрос (или близкие варианты) задавался тысячу раз. Я действительно провел несколько часов, глядя в очевидные и не столь очевидные места, но, может быть, я чего-то не хватает.
Контекст
Позвольте мне более четко определить проблему: я пишу приложение для рассылки новостей, в котором я хочу, чтобы фактический процесс отправки был асинхронным. Например, пользователь нажимает кнопку «отправить», запрос немедленно возвращается, и затем он может проверить ход выполнения на определенной странице (например, через AJAX). Это написано в вашем традиционном стеке LAMP.
В конкретном хосте, который я использую, PHP exec () и system () отключены по соображениям безопасности, а системные функции Perl (exec, system и backticks) - нет. Поэтому мое решение обходного пути заключалось в создании сценария «триггера» в Perl, который вызывает фактического отправителя через PHP CLI и перенаправляет на страницу прогресса.
Где я застрял
Самая строка звонков отправителю, на данный момент:
system("php -q sender.php &");
Проблема в том, что он не сразу возвращается, а ожидает завершения сценария. Я хочу, чтобы он работал в фоновом режиме и чтобы сам системный вызов сразу возвращался. Я также попытался запустить аналогичный сценарий в своем терминале Linux, и на самом деле приглашение не отображается до тех пор, пока сценарий не будет завершен, даже если мой тестовый вывод не запускается, указывая, что он действительно работает в фоновом режиме.
Что я уже пробовал
- Функция Perl exec () - тот же результат, что и для system ().
- Изменив команду на: "php -q sender.php | at now"), надеясь, что демон "at" вернется и что сам процесс PHP не будет присоединен к Perl.
- Выполнение команды 'косвенно': "/ bin / sh -c 'php -q sender.php &'" - все еще ожидает окончания отправки sender.php.
- fork (), выполняющий процесс и выполняющий системный вызов в дочернем процессе (возможно, отключенный процесс) - тот же результат, что и выше
Моя тестовая среда
Просто чтобы быть уверенным, что я не пропускаю ничего очевидного, я создал скрипт sleeper.php, который просто спит пять секунд перед выходом. И скрипт test.cgi, который выглядит так, дословно:
#!/usr/local/bin/perl
system("php sleeper.php &");
print "Content-type: text/html\n\ndone";
Что мне теперь попробовать?