0

I'm working on a programming online judge project like HackerRank,Codeforces etc...

I have thread pool and when requests comes, the web services gets a thread from thread pool and that thread compiles the code with ProcessBuilder(everything is okey until here), after the compilation, that thread starts execution part by using again a new Processbuilder. But my "time limit exceed" part is not calculated properly. When number of requests is increased, then I think that the process works slowly and for this reason any basic code gets time out. How can I measure the execution time of the code which is executed by a process ?(the measurement should not been affected by number of requests)

EDIT: my process should waitfor user time of the process.But I dont know how to do this.

My execution code is here:

    package org.anil.CodeChecker.process;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.concurrent.TimeUnit;

import org.anil.CodeChecker.model.ExecutorModel;

public class Executor {
    private ProcessBuilder p;
    private String path;
    private String input;
    private String output;
    private String lang;
    private long timeInMillis;

    public Executor(String path,String input, String output,String lang,long timeInMillis ){
        this.path = path;
        this.input = input;
        this.output = output;
        this.lang = lang;
        this.timeInMillis = timeInMillis;

    }


    public ExecutorModel execute(){
        ExecutorModel model = new ExecutorModel();

        System.out.println("Code started executing");

        if(lang.equals("java")){
            p = new ProcessBuilder("java","Solution");
        }
        else if(lang.equals("c")){
            p = new ProcessBuilder("./a.out");
        }
        else if(lang.equals("c++")){
            p = new ProcessBuilder("./a.out");
        }
        else{
            System.out.println("language is not correct...");
            p = null;
        }

        p.directory(new File(path));

        p.redirectErrorStream(true);

       // System.out.println("Current directory "+System.getProperty("user.dir"));

        try{
            Process pp = p.start();

            BufferedReader reader =
                    new BufferedReader(new InputStreamReader(pp.getInputStream()));
            StringBuilder builder = new StringBuilder();
            String line = null;



            /*process e input veriliyor bu kısımda */
            OutputStream outputstream = pp.getOutputStream();
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputstream));
            writer.write(input);

            writer.flush();
            writer.close();


            if(!pp.waitFor(timeInMillis, TimeUnit.MILLISECONDS)){
                System.out.println("TİME LİMİT EXCEED !!!! ");
                model.setTimelimit(true);       
                return model;
            }

            else{
                model.setTimelimit(false);
                int exitCode = pp.exitValue();
                System.out.println("Exit Value = "+pp.exitValue());

                if(exitCode != 0){
                    System.out.println("RUNTIME ERROR !!!!!!");

                    model.setSuccess(false);
                    model.setRuntimeerror(true);
                    return model;
                }
            }



            while ( (line = reader.readLine()) != null) {
                builder.append(line);
                //builder.append(System.getProperty("line.separator"));
            }
            String result = builder.toString();
            System.out.println(" output:"+result+" input:"+input);
            if(result.charAt(result.length()-1) == ' ')
                result = result.substring(0, result.length()-1);
            if(result.equals(output)){
                model.setSuccess(true);
                model.setWronganswer(false);
                System.out.println("OUTPUT (SUCCESS) = "+result);
                return model;
            }
            else{
                model.setSuccess(false);
                model.setWronganswer(true);
                System.out.println("OUTPUTTT (FAIL) = "+result);
                return model;
            }



        }catch(IOException ioe){
            System.err.println("in execute() "+ioe);
        }catch (InterruptedException ex){
            System.err.println(ex);
        }



        System.out.println("CODE EXECUTION FINISHED !");


        return model;
    }



}
Aksoy
  • 91
  • 1
  • 8
  • Possible duplicate of [Setting a maximum execution time for a method/thread](https://stackoverflow.com/questions/20500003/setting-a-maximum-execution-time-for-a-method-thread) – Sanket Makani May 26 '17 at 10:48
  • Just a side note : `lang.equals("java")` isn't safe, `"java".equals(lang)` is. And may the force be with you! – AxelH May 26 '17 at 11:05
  • @Sanket Makani ,I readed it, I already used it. The problem is measuring execution time of code which is executed by the process, not the execution time of the process – Aksoy May 26 '17 at 11:07
  • If on Unix instead of running your child program or Java directly, you can use the standard (and traditional) `time` utility to run your program and report its execution times and possibly other usage, on the error stream which you must read and parse. See `man time` on any sane Unix. – dave_thompson_085 May 26 '17 at 11:44

1 Answers1

0

Have you tryed to:

public long getCpuTime() {
    ThreadMXBean bean = ManagementFactory.getThreadMXBean();
    return bean.isCurrentThreadCpuTimeSupported() ? bean.getCurrentThreadCpuTime() : 0L; 
}

Using that method as the thread starting a process starts, and then use it again when that thread ends (since it then also ends the process as I understand it), then check delta (aka difference, last usage of the method minus first usage), to get the time how long that thread has been running, thus indirectly getting the time that the process took?

If Im not misstaken, that approach would be better then using for instance System.currentTimeMillis() since it counts the cpu time given to that specific thread, excluding time used by other threads as well as other system processes running in the background.

brat
  • 586
  • 5
  • 17