class_docstr: Object for monitoring
  
  Must be child of engine
  
  Handles signal messages and watches Engine process for exiting
class_docstr_tok: ["Object","for","monitoring","Must","be","child","of","engine","Handles","signal","messages","and","watches","Engine","process","for","exiting"]
docstr: Wait for my parent to exit, then I'll notify the controller and shut down
docstr_tok: ["Wait","for","my","parent","to","exit",",","then","I","'ll","notify","the","controller","and","shut","down"]
code: def wait_for_parent_thread(self):
      """Wait for my parent to exit, then I'll notify the controller and shut down"""
      self.log.info(f"Nanny watching parent pid {self.pid}.")
      while True:
          try:
              exit_code = self.parent_process.wait(60)
          except psutil.TimeoutExpired:
              continue
          else:
              break
      self.log.critical(
          f"Parent {self.pid} exited with status {exit_code}."
      )
      self.loop.add_callback(self.finish)
  
imports: import asyncio
  import logging
  import os
  import pickle
  import signal
  import sys
  from subprocess import PIPE, Popen
  from threading import Thread
  import psutil
  import zmq
  from jupyter_client.session import Session
  from tornado.ioloop import IOLoop
  from traitlets.config import Config
  from zmq.eventloop.zmqstream import ZMQStream
  from ipyparallel import error, util
  from ipyparallel.util import local_logger
label_desc: Use image node_id 2 for calling the KernelNanny obj's underlying member method code with example usage: obj.wait_for_parent_thread() without return types