开发者

php system() shell_exec() hangs the browser [duplicate]

This question already has answers here: Closed 11 years ago.

Possible Duplicate:

Asynchronous shell exec in PHP

i need to run a java program in the background.

process.php contains

shell_exec("php php_cli.php")

php_cli.php contains

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

I am calling process.php asynchronously using ajax

When i click the link in the webpage that calls ajax function (for running process.php) the webage shows "loading". when i click other links at the same time it does not responds.

The java program takes about 24 hours to finish executing, so user will not wait until the execution ends.

The problem is that the browser keeps on loading and does not go to other pages when c开发者_如何学Golicked the link.

I also tried with system(), but the same problem ....

Help will greatly be appreciated.


Using shell_exec waits for the command to hang up, so that's what your script is doing.

If your command doesn't have any wait time, then your script will not either.

You can call another PHP script from your original, without waiting for it to hang up:

$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.
    );

It is then possible to detect whether or not the script is finished by using this command:

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.
}


You could call the command in the page displayed, but appending an & at the end:

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

This way the process is launched on the background.

Also, there is no need (unless defined by your application) to create a process.php wich itself calls php via a shell exec. You could archive the same functionality via an include to the other file.


As in normal shell scripting you can use the ampersand to background the process:

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

See Asynchronous shell exec in PHP .


First, you might want to redesign this concept. I am not sure exactly what these programs do, but clearly this is can lead to potential problems...

This is what I suggest you do, instead of starting external processes via PHP:

  • Your ajax call creates (or reuse) a file in some temporary directory (probably using the user session to generate that file)
    • some data is written unto the file, and the request ends
  • Your jar is launched separately, and runs indefinitely
    • At regular intervals, the Java program scans the temporary directory for new files, or if some file has been modified
    • parse it, and execute the 24 hour long process, or adjust any previous execution if necessary

Along the same idea, you can even use sockets instead to communicate with that Java program, or any other way.

The advantage of having the Java program running all the time instead of starting a new process is to be able to reuse system resources within the lifetime of the application; for example, if your program is using DB connections, or any data, cache, etc.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜