code: def test_multi_driver_logging(ray_start_regular):
      address = ray_start_regular["address"]
  
      # ray.init(address=address)
      driver1_wait = Semaphore.options(name="driver1_wait").remote(
          value=0
      )
      driver2_wait = Semaphore.options(name="driver2_wait").remote(
          value=0
      )
      main_wait = Semaphore.options(name="main_wait").remote(value=0)
  
      # The creation of an actor is asynchronous.
      # We need to wait for the completion of the actor creation,
      # otherwise we can't get the actor by name.
      ray.get(driver1_wait.locked.remote())
      ray.get(driver2_wait.locked.remote())
      ray.get(main_wait.locked.remote())
  
      # Params are address, semaphore name, output1, output2
      driver_script_template = """
  import ray
  import sys
  from ray._private.test_utils import Semaphore
  
  @ray.remote(num_cpus=0)
  def remote_print(s, file=None):
      print(s, file=file)
  
  ray.init(address="{}", namespace="default_test_namespace")
  
  driver_wait = ray.get_actor("{}")
  main_wait = ray.get_actor("main_wait")
  
  ray.get(main_wait.release.remote())
  ray.get(driver_wait.acquire.remote())
  
  s1 = "{}"
  ray.get(remote_print.remote(s1))
  
  ray.get(main_wait.release.remote())
  ray.get(driver_wait.acquire.remote())
  
  s2 = "{}"
  ray.get(remote_print.remote(s2))
  
  ray.get(main_wait.release.remote())
      """
  
      p1 = run_string_as_driver_nonblocking(
          driver_script_template.format(
              address, "driver1_wait", "message1", "message2"
          )
      )
      p2 = run_string_as_driver_nonblocking(
          driver_script_template.format(
              address, "driver2_wait", "message3", "message4"
          )
      )
  
      ray.get(main_wait.acquire.remote())
      ray.get(main_wait.acquire.remote())
      # At this point both of the other drivers are fully initialized.
  
      ray.get(driver1_wait.release.remote())
      ray.get(driver2_wait.release.remote())
  
      # At this point driver1 should receive 'message1' and driver2 'message3'
      ray.get(main_wait.acquire.remote())
      ray.get(main_wait.acquire.remote())
  
      ray.get(driver1_wait.release.remote())
      ray.get(driver2_wait.release.remote())
  
      # At this point driver1 should receive 'message2' and driver2 'message4'
      ray.get(main_wait.acquire.remote())
      ray.get(main_wait.acquire.remote())
  
      driver1_out = p1.stdout.read().decode("ascii")
      driver2_out = p2.stdout.read().decode("ascii")
  
      assert "message1" in driver1_out
      assert "message2" in driver1_out
      assert "message3" in driver2_out
      assert "message4" in driver2_out
  
imports: import asyncio
  import os
  import subprocess
  import sys
  from pathlib import Path
  import psutil
  import pytest
  import ray
  import ray._private.ray_constants
  from ray._private.test_utils import Semaphore, check_call_ray, check_call_subprocess, kill_process_by_name, start_redis_instance, run_string_as_driver, run_string_as_driver_nonblocking, wait_for_children_of_pid, wait_for_children_of_pid_to_exit
  from ray._private.utils import detect_fate_sharing_support
label_desc: Use image node_id 7 for calling a global function with example usage: test_multi_driver_logging(ray_start_regular) without return types