php system() shell exec() зависает браузер [дубликат]
Возможный Дубликат:
Асинхронный shell exec в PHP
Мне нужно запустить программу java в фоновом режиме.
Process.php содержит
shell_exec("php php_cli.php")
Php_cli.php содержит
shell_exec("java -jar BiForce.jar settings.ini > log.txt");
Я звоню process.php асинхронно с использованием ajax
Когда я нажимаю ссылку на веб-странице, которая вызывает функцию ajax (для запуска process.php ) на веб-странице отображается "загрузка". когда я одновременно нажимаю на другие ссылки, это не отвечает.
Для завершения выполнения java-программы требуется около 24 часов, поэтому пользователь не будет ждать окончания выполнения.
Проблема в том, что браузер продолжает загружаться и не переходит на другие страницы при нажатии на ссылку.
Я также пытался использовать system(), но та же проблема....
Помощь будет очень признательна.
4 answers
Вы можете вызвать команду на отображаемой странице, но добавив & в конце:
shell_exec("java -jar BiForce.jar settings.ini > log.txt &");
Таким образом, процесс запускается в фоновом режиме.
Кроме того, нет необходимости (если это не определено вашим приложением) создавать process.php который сам вызывает php через оболочку exec. Вы можете заархивировать ту же функциональность с помощью включения в другой файл.
С помощью shell_exec
ожидает, пока команда повесит трубку, так что это то, что делает ваш скрипт.
Если у вашей команды нет времени ожидания, то и у вашего скрипта его тоже не будет.
Вы можете вызвать другой PHP-скрипт из своего оригинала, не дожидаясь, пока он повесит трубку:
$processId = shell_exec(
"nohup " . // Runs a command, ignoring hangup signals.
"nice " . // "Adjusted niceness" :) Read nice --help
"/usr/bin/php -c " . // Path to your PHP executable.
"/path/to/php.ini -f " . // Path to your PHP config.
"/var/www/php_cli.php " . // Path to the script you want to execute.
"action=generate > /process.log " . // Log file.
"& echo $!" // Make sure it returns only the process id.
);
Затем можно определить, завершен ли сценарий, используя следующую команду:
exec('ps ' . $processId, $processState);
// exec returns the result of the command - but we need to store the process state.
// The third param is a referenced variable.
// First key in $processState is that it's running.
// Second key would be that it has exited.
if (count($processState) < 2) {
// Process has ended.
}
Как и в обычных сценариях оболочки, вы можете использовать амперсанд для фонового процесса:
shell_exec("java -jar BiForce.jar settings.ini > log.txt &");
Смотрите Асинхронный shell exec в PHP .
Во-первых, вы, возможно, захотите изменить эту концепцию. Я не совсем уверен, что именно делают эти программы, но очевидно, что это может привести к потенциальным проблемам...
Вот что я предлагаю вам сделать вместо запуска внешних процессов с помощью PHP:
- Ваш вызов ajax создает (или повторно использует) файл в каком-либо временном каталоге (возможно, используя сеанс пользователя для создания этого файла)
- некоторые данные записываются в файл, и запрос завершается
- Ваша банка запускается отдельно и работает бесконечно
- Через регулярные промежутки времени программа Java сканирует временный каталог на наличие новых файлов или, если какой-либо файл был изменен
- проанализируйте его и выполните 24-часовой процесс или при необходимости скорректируйте любое предыдущее выполнение
Следуя той же идее, вы можете даже использовать сокеты вместо этого для связи с этой программой Java или любым другим способом.
Преимущество того, что вместо этого все время работает программа Java для запуска нового процесса необходимо иметь возможность повторно использовать системные ресурсы в течение срока службы приложения; например, если ваша программа использует подключения к БД или любые данные, кэш и т. Д.