我使用 Google Closure Compiler 使用 PHP 自动编译 javascript(需要这样做 - 在 PHP 中,在 Windows 机器上没有安全限制)。我编写了简单的 PHP 脚本来调用进程,将 .js 内容传递给标准输入并通过标准输出接收重新编译的 .js。它工作正常,问题是,当我编译 40 个 .js 文件时,它在强大的机器上花费了将近 2 分钟。但是,市长延迟是因为 java 为每个脚本启动了新的 .jar 应用程序实例。有什么方法可以修改下面的脚本以仅创建一个进程并在进程结束前多次发送/接收 .js 内容?
function compileJScript($s) {
$process = proc_open('java.exe -jar compiler.jar', array(
0 => array("pipe", "r"), 1 => array("pipe", "w")), $pipes);
if (is_resource($process)) {
fwrite($pipes[0], $s);
fclose($pipes[0]);
$output = stream_get_contents($pipes[1]);
fclose($pipes[1]);
if (proc_close($process) == 0) // If fails, keep $s intact
$s = $output;
}
return $s;
}
我可以看到几个选项,但不知道是否可行以及如何执行:
- 创建一次进程并为每个文件只重新创建管道
- 强制 java 将 JIT-ed .jar 保存在内存中以便更快地重新执行
- 如果 PHP 做不到,可以使用桥接(另一个 .exe 文件,每次都会快速启动,传输 stdin/out 并将其重定向到运行的编译器;如果这样的东西甚至存在)
最佳答案
这实际上是两个过程之间的协调问题。
在这里我写了一个 10 分钟的快速脚本(只是为了好玩),它启动一个 JVM 并发送一个整数值,java 解析并返回递增的.. PHP 将把它发回 ad-infinitum..
PHP.php
<?php
echo 'Compiling..', PHP_EOL;
system('javac Java.java');
echo 'Starting JVM..', PHP_EOL;
$pipes = null;
$process = proc_open('java Java', [0 => ['pipe', 'r'],
1 => ['pipe', 'w']], $pipes);
if (!is_resource($process)) {
exit('ERR: Cannot create java process');
}
list($javaIn, $javaOut) = $pipes;
$i = 1;
while (true) {
fwrite($javaIn, $i); // <-- send the number
fwrite($javaIn, PHP_EOL);
fflush($javaIn);
$reply = fgetss($javaOut); // <-- blocking read
$i = intval($reply);
echo $i, PHP_EOL;
sleep(1); // <-- wait 1 second
}
Java.java
import java.util.Scanner;
class Java {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
while (s.hasNextInt()) { // <-- blocking read
int i = s.nextInt();
System.out.print(i + 1); // <-- send it back
System.out.print('\n');
System.out.flush();
}
}
}
要运行脚本,只需将这些文件放在同一个文件夹中,然后执行
$ php PHP.php
您应该开始看到正在打印的数字,如下所示:
1
2
3
.
.
.
请注意,虽然这些数字是由 PHP 打印的,但它们实际上是由 Java 生成的
关于java - 一个进程调用期间的多个标准输入/标准输出操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25755791/