code: def process_items_concurrently(
      self,
      item_iterator,
      process_func=lambda x: x,
      pre_func=lambda x: x,
      post_func=lambda x: x,
      max_items_in_flight=None,
  ):
      if max_items_in_flight is None:
          max_items_in_flight = self.num_threads * 4
      assert max_items_in_flight >= 1
      results = []
      retire_idx = [0]
  
      def task_func(prepared, _idx):
          return process_func(prepared)
  
      def retire_result():
          processed, (_prepared, idx) = self.get_result(task_func)
          results[idx] = processed
          while (
              retire_idx[0] < len(results)
              and results[retire_idx[0]] is not None
          ):
              yield post_func(results[retire_idx[0]])
              results[retire_idx[0]] = None
              retire_idx[0] += 1
  
      for idx, item in enumerate(item_iterator):
          prepared = pre_func(item)
          results.append(None)
          self.add_task(func=task_func, args=(prepared, idx))
          while retire_idx[0] < idx - max_items_in_flight + 2:
              for res in retire_result():
                  yield res
      while retire_idx[0] < len(results):
          for res in retire_result():
              yield res
  
imports: import os
  import sys
  import glob
  import argparse
  import threading
  import six.moves.queue
  import traceback
  import numpy
  import tensorflow
  import PIL.Image
  import dnnlib.tflib
  from training import dataset
label_desc: Use image node_id 7 for calling the ThreadPool obj's underlying member method code with example usage: obj.process_items_concurrently(item_iterator, process_func, pre_func, post_func, max_items_in_flight) and returns: process_func