code: def delete_shell(self, pid):
          
          try:
              os.kill(pid, signal.SIGHUP)
          except OSError:
              pass
          num_tries = 30
  
          while num_tries > 0:
              try:
                  # Try to wait for the pid to be closed. If it does not
                  # exist anymore, an OSError is raised and we can
                  # safely ignore it.
                  if os.waitpid(pid, os.WNOHANG)[0] != 0:
                      break
              except OSError:
                  break
              sleep(0.1)
              num_tries -= 1
  
          if num_tries == 0:
              try:
                  os.kill(pid, signal.SIGKILL)
                  os.waitpid(pid, 0)
              except OSError:
                  # if this part of code was reached, means that SIGTERM
                  # did the work and SIGKILL wasnt needed.
                  pass
docs: This function will kill the shell on a tab, trying to send
          a sigterm and if it doesn't work, a sigkill. Between these two
          signals, we have a timeout of 3 seconds, so is recommended to
          call this in another thread. This doesn't change any thing in
          UI, so you can use python's start_new_thread.