code: def monitor(seconds_frozen, test_interval):
      
      current_thread = threading.current_thread()
      hanging_threads = set()
      old_threads = {}  # Threads found on previous iteration.
  
      while not current_thread.is_stopped():
          new_threads = get_current_frames()
  
          # Report died threads.
          for thread_id in old_threads.keys():
              if thread_id not in new_threads and thread_id in hanging_threads:
                  log_died_thread(thread_id)
  
          # Process live threads.
          time.sleep(test_interval/1000.)
          now = time.time()
          then = now - seconds_frozen
          for thread_id, thread_data in new_threads.items():
              # Don't report the monitor thread.
              if thread_id == current_thread.ident:
                  continue
              frame = thread_data['frame']
              # If thread is new or it's stack is changed then update time.
              if (thread_id not in old_threads or
                      frame != old_threads[thread_id]['frame']):
                  thread_data['time'] = now
                  # If the thread was hanging then report awaked thread.
                  if thread_id in hanging_threads:
                      hanging_threads.remove(thread_id)
                      log_awaked_thread(thread_id)
              else:
                  # If stack is not changed then keep old time.
                  last_change_time = old_threads[thread_id]['time']
                  thread_data['time'] = last_change_time
                  # Check if this is a new hanging thread.
                  if (thread_id not in hanging_threads and
                          last_change_time < then):
                      # Gotcha!
                      hanging_threads.add(thread_id)
                      # Report the hanged thread.
                      log_hanged_thread(thread_id, frame)
          old_threads = new_threads
docs: Monitoring thread function.
  
      Checks if thread is hanging for time defined by
      ``seconds_frozen`` parameter every ``test_interval`` milliseconds.