Changeset 13309


Ignore:
Timestamp:
11/19/15 17:54:28 (3 years ago)
Author:
gkronber
Message:

#2069: added synchronization for the evaluation of robocode programs

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Interpreter.cs

    r13210 r13309  
    3131namespace HeuristicLab.Problems.GeneticProgramming.Robocode {
    3232  public static class Interpreter {
     33
     34    // necessary for synchronization to guarantee that only one robocode program is executed at the same time
     35    // NOTE: this does not guarantee OS-wide mutual exclusion, but we ignore that for now
     36    private static readonly object syncRoot = new object();
     37
    3338    // TODO performance: it would probably be useful to implement the BattleRunner in such a way that we don't have to restart the java process each time, e.g. using console IO to load & run robots
    3439    public static double EvaluateTankProgram(ISymbolicExpressionTree tree, string path, EnemyCollection enemies, string robotName = null, bool showUI = false, int nrOfRounds = 3) {
     
    5661      javaCompileInfo.CreateNoWindow = true;
    5762
     63      // it's ok to compile multiple robocode programs concurrently
    5864      using (Process javaCompile = new Process()) {
    5965        javaCompile.StartInfo = javaCompileInfo;
     
    7076      }
    7177
    72       //parallel execution of multiple robocode instances can sometimes lead to a damaged robot.database
    73       var robotsDbFileName = Path.Combine(path, "robots", "robot.database");
    74       if (File.Exists(robotsDbFileName))
    75         File.Delete(robotsDbFileName);
    76 
    7778      ProcessStartInfo evaluateCodeInfo = new ProcessStartInfo();
    7879
     
    8990      evaluateCodeInfo.CreateNoWindow = true;
    9091
     92      // the robocode framework writes state to a file therefore parallel evaluation of multiple robocode programs is not possible yet.
    9193      double evaluation;
    92       using (Process evaluateCode = new Process()) {
    93         evaluateCode.StartInfo = evaluateCodeInfo;
    94         evaluateCode.Start();
    95         evaluateCode.WaitForExit();
    96 
    97         if (evaluateCode.ExitCode != 0) {
    98           DeleteRobotFiles(path, robotName);
    99           throw new Exception("Error running Robocode: " + evaluateCode.StandardError.ReadToEnd() + Environment.NewLine +
    100                               evaluateCode.StandardOutput.ReadToEnd());
    101         }
    102 
    103         try {
    104           string scoreString =
    105             evaluateCode.StandardOutput.ReadToEnd()
    106               .Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
    107               .Last();
    108           evaluation = Double.Parse(scoreString, CultureInfo.InvariantCulture);
    109         }
    110         catch (Exception ex) {
    111           throw new Exception("Error parsing score string: " + ex);
    112         }
    113         finally {
    114           DeleteRobotFiles(path, robotName);
     94      lock (syncRoot) {
     95        using (Process evaluateCode = new Process()) {
     96          evaluateCode.StartInfo = evaluateCodeInfo;
     97          evaluateCode.Start();
     98          evaluateCode.WaitForExit();
     99
     100          if (evaluateCode.ExitCode != 0) {
     101            DeleteRobotFiles(path, robotName);
     102            throw new Exception("Error running Robocode: " + evaluateCode.StandardError.ReadToEnd() +
     103                                Environment.NewLine +
     104                                evaluateCode.StandardOutput.ReadToEnd());
     105          }
     106
     107          try {
     108            string scoreString =
     109              evaluateCode.StandardOutput.ReadToEnd()
     110                .Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
     111                .Last();
     112            evaluation = Double.Parse(scoreString, CultureInfo.InvariantCulture);
     113          }
     114          catch (Exception ex) {
     115            throw new Exception("Error parsing score string: " + ex);
     116          }
     117          finally {
     118            DeleteRobotFiles(path, robotName);
     119          }
    115120        }
    116121      }
Note: See TracChangeset for help on using the changeset viewer.