5

重複の可能性:
PHP での非同期シェル exec

バックグラウンドで Java プログラムを実行する必要があります。

process.php が含まれています

shell_exec("php php_cli.php")

php_cli.php が含まれています

shell_exec("java -jar BiForce.jar settings.ini > log.txt");

ajaxを使用して非同期でprocess.phpを呼び出しています

(process.php を実行するための) ajax 関数を呼び出す Web ページのリンクをクリックすると、Web ページに「読み込み中」と表示されます。同時に他のリンクをクリックしても反応しません。

Java プログラムは実行が完了するまでに約 24 時間かかるため、ユーザーは実行が終了するまで待機しません。

問題は、ブラウザがロードを続け、リンクをクリックしても他のページに移動しないことです。

system()でも試してみましたが、同じ問題が....

助けていただければ幸いです。

4

4 に答える 4

5

コマンドがハングアップするのを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.
}
于 2011-06-03T07:53:24.177 に答える
2

表示されたページでコマンドを呼び出すことができますが、最後に&を追加します。

shell_exec("java -jar BiForce.jar settings.ini > log.txt &");

このようにして、プロセスはバックグラウンドで起動されます。

また、(アプリケーションで定義されていない限り)シェル exec を介してそれ自体が php を呼び出す process.php を作成する必要はありません。インクルードを介して同じ機能を他のファイルにアーカイブできます。

于 2011-06-03T07:44:31.237 に答える
0

まず、この概念を再設計することをお勧めします。これらのプログラムが何をするのか正確にはわかりませんが、明らかにこれは潜在的な問題につながる可能性があります...

PHP経由で外部プロセスを開始する代わりに、これを行うことをお勧めします。

  • あなたのajax呼び出しは、一時ディレクトリにファイルを作成(または再利用)します(おそらくユーザーセッションを使用してそのファイルを生成します)
    • 一部のデータがファイルに書き込まれ、リクエストが終了します
  • jar は個別に起動され、無期限に実行されます
    • 一定の間隔で、Java プログラムは一時ディレクトリをスキャンして新しいファイルがないか、またはファイルが変更されているかどうかを調べます。
    • それを解析し、24 時間のプロセスを実行するか、必要に応じて以前の実行を調整します

同じ考え方に沿って、代わりにソケットを使用してその Java プログラムと通信したり、その他の方法で通信したりすることもできます。

新しいプロセスを開始する代わりに Java プログラムを常時実行する利点は、アプリケーションの有効期間内にシステム リソースを再利用できることです。たとえば、プログラムが DB 接続、またはデータ、キャッシュなどを使用している場合。

于 2011-06-03T07:46:54.477 に答える
0

通常のシェル スクリプトと同様に、アンパサンドを使用してプロセスをバックグラウンドにすることができます。

shell_exec("java -jar BiForce.jar settings.ini > log.txt &");

PHP での非同期シェル exec を参照してください。

于 2011-06-03T07:44:26.853 に答える