class_docstr: Monitor to keep track of all clients using this service.
  
  This is only used for services that use multiple clients, e.g. the database
  service. In addition to tracking the original parent process, other
  processes can also request to be tracked by sending a message to this
  process as a tuple: ("register", PID). trigger_exit(PARENT) is only called
  after the original parent and all registered clients have shut down.
class_docstr_tok: ["Monitor","to","keep","track","of","all","clients","using","this","service",".","This","is","only","used","for","services","that","use","multiple","clients",",","e.g",".","the","database","service",".","In","addition","to","tracking","the","original","parent","process",",","other","processes","can","also","request","to","be","tracked","by","sending","a","message","to","this","process","as","a","tuple",":","(","``","register","''",",","PID",")",".","trigger_exit","(","PARENT",")","is","only","called","after","the","original","parent","and","all","registered","clients","have","shut","down","."]
docstr: Creates and starts a client monitor.
docstr_tok: ["Creates","and","starts","a","client","monitor","."]
code: def __init__(self):
      """Creates and starts a client monitor."""
      # This has an internal lock, so it is reused for any operations that
      # need to be synchronized
      self.cond = threading.Condition()
      # A set of clients (psutil.Process objects, which are hashable).
      # As long as monitor_stdin() hasn't been called yet, we can assume the
      # parent is still alive, and this can be changed later
      self.clients = {ClientMonitor._PARENT}
      # start background tasks
      self.thread = start_daemon_thread(target=self._background_loop)
      self.server = IPCServer.run_in_background(
          on_message=self._handle_message
      )
  
imports: import argparse
  import collections
  import enum
  import os
  import signal
  import subprocess
  import sys
  import threading
  import traceback
  import psutil
  from fiftyone.service.ipc import IPCServer
label_desc: Use image node_id 1 to create a new ClientMonitor object from inherited base classes: object with example: obj = ClientMonitor()