def call_program(self, cmd, limit=None, memory_limit=None, **kwargs):
    the_io_thread_pool_init(self.args.parallelism)
    if limit is float('inf'):
      limit = None
    if type(cmd) in (str, unicode):
      kwargs['shell'] = True
    killed = False
    t0 = time.time()
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                         preexec_fn=preexec_setpgid_setrlimit(memory_limit),
                         **kwargs)
    # Add p.pid to list of processes to kill in case of keyboardinterrupt
    self.pid_lock.acquire()
    self.pids.append(p.pid)
    self.pid_lock.release()

    try:
      stdout_result = the_io_thread_pool.apply_async(p.stdout.read)
      stderr_result = the_io_thread_pool.apply_async(p.stderr.read)
      while p.returncode is None:
        if limit is None:
          goodwait(p)
        elif limit and time.time() > t0 + limit:
          killed = True
          goodkillpg(p.pid)
          goodwait(p)
        else:
          # still waiting...
          sleep_for = limit - (time.time() - t0)
          if not stdout_result.ready():
            stdout_result.wait(sleep_for)
          elif not stderr_result.ready():
            stderr_result.wait(sleep_for)
          else:
            #TODO(jansel): replace this with a portable waitpid
            time.sleep(0.001)
        p.poll()
    except:
      if p.returncode is None:
        goodkillpg(p.pid)
      raise
    finally:
      # No longer need to kill p
      self.pid_lock.acquire()
      if p.pid in self.pids:
        self.pids.remove(p.pid)
      self.pid_lock.release()

    t1 = time.time()
    return {'time': float('inf') if killed else (t1 - t0),
            'timeout': killed,
            'returncode': p.returncode,
            'stdout': stdout_result.get(),
            'stderr': stderr_result.get()}
call cmd and kill it if it runs for longer than limit
dataset/ETHPy150Open jansel/opentuner/opentuner/measurement/interface.py/MeasurementInterface.call_program