一个进程调用期间的多个stdin / stdout操作

时间:2014-09-10 01:01:04

标签: java php google-closure-compiler

我使用Google Closure Compiler使用PHP自动编译javascript(需要这样做 - 在PHP中,在Windows机器上没有安全限制)。我编写了简单的PHP脚本来调用进程,将.js内容传递给stdin并通过stdout接收重新编译的.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;
}

我可以看到几个选项,但不知道是否可行以及如何操作:

  1. 创建一次流程并仅为每个文件重新创建管道
  2. 强制java将JIT-ed .jar保留在内存中,以便更快地重新执行
  3. 如果PHP无法做到,可以使用bridge(另一个.exe文件,每次都会快速启动,传输stdin / out并将其重定向到正在运行的编译器;如果这样的话甚至存在)

2 个答案:

答案 0 :(得分:5)

这实际上是两个过程之间协调的问题。

在这里,我编写了一个快速的10分钟脚本(只是为了好玩),它启动了一个JVM并发送一个整数值,java解析并返回递增的值...... PHP将把它发回给 ad-infinitum < / EM> ..

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生成的

答案 1 :(得分:0)

我不认为列表中的#1是可能的,因为compiler.jar需要原生支持才能使进程保持活动状态,而不是(并且如果您认为压缩算法需要整个在它开始处理数据之前输入,这个过程不会保持活跃是有道理的)。

根据Anyway to Boost java JVM Startup Speed?,有些人能够通过nailgun

减少他们的jvm启动时间
  

Nailgun是用于运行Java程序的客户端,协议和服务器   从命令行,不会产生JVM启动开销。   程序在服务器中运行(用Java实现),并且是   由客户端(用C语言编写)触发,它处理所有I / O.