class_docstr: This controls a job:
  - instantiate each of the tasks
  - sends timeout signal
  - stops all tasks if one of them finishes
  - cleans up the tasks/closes log files when deleted
class_docstr_tok: ["This","controls","a","job",":","-","instantiate","each","of","the","tasks","-","sends","timeout","signal","-","stops","all","tasks","if","one","of","them","finishes","-","cleans","up","the","tasks\/closes","log","files","when","deleted"]
code: def kill_tasks(self) -> None:
      # try and be progressive in deletion...
      for sig in [signal.SIGINT, signal.SIGKILL]:
          self._forward_signal(sig)
          # if one is still alive after sigterm and sigint, try sigkill after 1s
          if sig == signal.SIGINT and any(
              t.poll() is None for t in self.tasks
          ):
              time.sleep(0.001)
              if any(t.poll() is None for t in self.tasks):
                  time.sleep(1.0)  # wait a bit more
      self.tasks = []
      files = self.stdouts + self.stderrs
      self.stdouts, self.stderrs = (
          [],
          [],
      )  # remove all instance references
      for f in files:
          f.close()
  
imports: import os
  import shlex
  import signal
  import subprocess
  import sys
  import time
  import typing
  from pathlib import Path
  from ..core import core, job_environment, logger, utils
  from ..core.core import R
label_desc: Use image node_id 4 for calling the Controller obj's underlying member method code with example usage: obj.kill_tasks() without return types