docstr: Initializes a thread pool.
  
  TODO: consider using a standard thread pool
  (e.g. http://elliothallmark.com/2016/12/23/requests-with-concurrent-futures-in-python-2-7/ as an implementation)
  
  Originally implemented our own pool to match the interface of ProcessPool (could not find a process pool
  implementation that would not use fork)
  
  :param workers_count: Number of threads
  :param profile: Whether to run a profiler on the threads
docstr_tok: ["Initializes","a","thread","pool",".","TODO",":","consider","using","a","standard","thread","pool","(","e.g",".","http",":","\/\/elliothallmark.com\/2016\/12\/23\/requests-with-concurrent-futures-in-python-2-7\/","as","an","implementation",")","Originally","implemented","our","own","pool","to","match","the","interface","of","ProcessPool","(","could","not","find","a","process","pool","implementation","that","would","not","use","fork",")",":","param","workers_count",":","Number","of","threads",":","param","profile",":","Whether","to","run","a","profiler","on","the","threads"]
code: def __init__(
      self,
      workers_count,
      results_queue_size=50,
      profiling_enabled=False,
  ):
      """Initializes a thread pool.
  
      TODO: consider using a standard thread pool
      (e.g. http://elliothallmark.com/2016/12/23/requests-with-concurrent-futures-in-python-2-7/ as an implementation)
  
      Originally implemented our own pool to match the interface of ProcessPool (could not find a process pool
      implementation that would not use fork)
  
      :param workers_count: Number of threads
      :param profile: Whether to run a profiler on the threads
      """
      self._seed = random.randint(0, 100000)
      self._workers = []
      self._ventilator_queue = None
      self.workers_count = workers_count
      self._results_queue_size = results_queue_size
      # Worker threads will watch this event and gracefully shutdown when the event is set
      self._stop_event = Event()
      self._profiling_enabled = profiling_enabled
  
      self._ventilated_items = 0
      self._ventilated_items_processed = 0
      self._ventilator = None
  
imports: import cProfile
  import pstats
  import random
  import sys
  from threading import Thread, Event
  from traceback import format_exc
  from six.moves import queue
  from petastorm.workers_pool import EmptyResultError, VentilatedItemProcessedMessage
label_desc: Use image node_id 1 to create a new ThreadPool object from inherited base classes: object with example: obj = ThreadPool(workers_count, results_queue_size, profiling_enabled)