code: def test_threads_terminate(self):
      def acquire_lock(lock):
          lock.acquire()
  
      sem = threading.Semaphore(0)
      for i in range(3):
          self.executor.submit(acquire_lock, sem)
      self.assertEqual(len(self.executor._threads), 3)
      for i in range(3):
          sem.release()
      self.executor.shutdown()
      for t in self.executor._threads:
          t.join()
  
imports: import signal
  import sys
  import threading
  import time
  import unittest
  from concurrent import futures
  from test import support
  from test.support.script_helper import assert_python_ok
  from .util import BaseTestCase, ThreadPoolMixin, ProcessPoolForkMixin, ProcessPoolForkserverMixin, ProcessPoolSpawnMixin, create_executor_tests, setup_module
label_desc: Use image node_id 1 for calling the ThreadPoolShutdownTest obj's underlying member method code with example usage: obj.test_threads_terminate() without return types