code: def attach_sub_process(
      self, external_address: str, process: SubProcessHandle
  ):
      self.sub_processes[external_address] = process
  
imports: import asyncio
  import concurrent.futures
  import itertools
  import logging
  import multiprocessing
  import os
  import threading
  import traceback
  from abc import ABC, ABCMeta, abstractmethod
  from typing import Dict, List, Type, TypeVar, Coroutine, Callable, Union, Optional
  from ...core.entrypoints import init_extension_entrypoints
  from ...metrics import init_metrics
  from ...utils import implements, to_binary
  from ...utils import lazy_import, register_asyncio_task_timeout_detector, TypeDispatcher
  from ..api import Actor
  from ..core import ActorRef, register_local_pool
  from ..debug import record_message_trace, debug_async_timeout
  from ..errors import ActorAlreadyExist, ActorNotExist, ServerClosed, CannotCancelTask, SendMessageFailed
  from ..utils import create_actor_ref
  from .allocate_strategy import allocated_type, AddressSpecified
  from .communication import Channel, Server, get_server_type, gen_local_address
  from .communication.errors import ChannelClosed
  from .config import ActorPoolConfig
  from .core import ResultMessageType, ActorCaller
  from .message import _MessageBase, new_message_id, DEFAULT_PROTOCOL, MessageType, ResultMessage, ErrorMessage, CreateActorMessage, HasActorMessage, DestroyActorMessage, ActorRefMessage, SendMessage, TellMessage, CancelMessage, ControlMessage, ControlMessageType
  from .router import Router
label_desc: Use image node_id 5 for calling the MainActorPoolBase obj's underlying member method code with example usage: obj.attach_sub_process(external_address, process) without return types