code: def test_multi_thread_rpc():
      reset_envs()
      os.environ["DGL_DIST_MODE"] = "distributed"
      num_servers = 2
      ip_config = "rpc_ip_config_multithread.txt"
      generate_ip_config(ip_config, num_servers, num_servers)
      ctx = mp.get_context("spawn")
      pserver_list = []
      for i in range(num_servers):
          pserver = ctx.Process(
              target=start_server, args=(1, ip_config, i, 1)
          )
          pserver.start()
          pserver_list.append(pserver)
  
      def start_client_multithread(ip_config):
          import threading
  
          dgl.distributed.connect_to_server(
              ip_config=ip_config,
              num_servers=1,
          )
          dgl.distributed.register_service(
              HELLO_SERVICE_ID, HelloRequest, HelloResponse
          )
  
          req = HelloRequest(STR, INTEGER, TENSOR, simple_func)
          dgl.distributed.send_request(0, req)
  
          def subthread_call(server_id):
              req = HelloRequest(STR, INTEGER, TENSOR, simple_func)
              dgl.distributed.send_request(server_id, req)
  
          subthread = threading.Thread(target=subthread_call, args=(1,))
          subthread.start()
          subthread.join()
  
          res0 = dgl.distributed.recv_response()
          res1 = dgl.distributed.recv_response()
          # Order is not guaranteed
          assert_array_equal(F.asnumpy(res0.tensor), F.asnumpy(TENSOR))
          assert_array_equal(F.asnumpy(res1.tensor), F.asnumpy(TENSOR))
          dgl.distributed.exit_client()
  
      start_client_multithread(ip_config)
      pserver.join()
  
imports: import multiprocessing
  import os
  import socket
  import time
  import unittest
  import backend
  import dgl
  import pytest
  from numpy.testing import assert_array_equal
  from utils import generate_ip_config, reset_envs
label_desc: Use image node_id 10 for calling a global function with example usage: test_multi_thread_rpc() without return types