docstr: Test that cached_func_stack behaves properly in multiple threads.
docstr_tok: ["Test","that","cached_func_stack","behaves","properly","in","multiple","threads","."]
code: def test_multithread_stack(self):
      """Test that cached_func_stack behaves properly in multiple threads."""
  
      def get_counter():
          return len(caching._cache_info.cached_func_stack)
  
      def set_counter(val):
          caching._cache_info.cached_func_stack = ["foo"] * val
  
      self.assertEqual(0, get_counter())
      set_counter(1)
      self.assertEqual(1, get_counter())
  
      values_in_thread = []
  
      def thread_test():
          values_in_thread.append(get_counter())
          set_counter(55)
          values_in_thread.append(get_counter())
  
      thread = threading.Thread(target=thread_test)
      thread.start()
      thread.join()
  
      self.assertEqual([0, 55], values_in_thread)
  
      # The other thread should not have modified the main thread
      self.assertEqual(1, get_counter())
  
imports: import threading
  import types
  from unittest.mock import Mock, patch
  from parameterized import parameterized
  import streamlit
  from streamlit.elements import exception
  from streamlit.proto.Exception_pb2 import Exception
  from streamlit.runtime.legacy_caching import caching, hashing
  from tests import testutil
  from tests.delta_generator_test_case import DeltaGeneratorTestCase
label_desc: Use image node_id 8 for calling the CacheTest obj's underlying member method code with example usage: obj.test_multithread_stack() and returns: len