What is relationship of run_phase and main_phase?

In reply to dave_59:

Thanks for your reply, Dave.
I will follow your advice(raise an objection in any task-based phase) in my real project.
but I am really curious with the relationship of run_phase and main_phase(run time phase).
In many papers or UVM spec, they all told me that run_phase and run time phase execute concurrently.
but Compare the above code, why the following code run, uvm can print “TEST” and “ENV” message.
They don’t look like a simple parallel relationship.


`timescale 1ns/1ps
 
module tb();
   import  uvm_pkg::*;
   `include "uvm_macros.svh"
 
   class sys_env extends uvm_env;
       `uvm_component_utils(sys_env)
 
       function new(string name, uvm_component parent);
           super.new(name, parent);
       endfunction
 
       function void build_phase(uvm_phase phase);
           super.build_phase(phase);
       endfunction
 
       task main_phase(uvm_phase phase);
           phase.raise_objection(this);
           #40ns;
           `uvm_info("ENV", "sys_env run over!", UVM_LOW)
           phase.drop_objection(this);
       endtask
    endclass
 
    class sys_test extends uvm_env;
       `uvm_component_utils(sys_test)
       sys_env   m_env;
 
       function new(string name, uvm_component parent);
           super.new(name, parent);
       endfunction
 
       function void build_phase(uvm_phase phase);
           super.build_phase(phase);
           m_env = sys_env::type_id::create("m_env", this);
       endfunction
 
       task run_phase(uvm_phase phase);
           //phase.raise_objection(this);
           #20ns;
           `uvm_info("TEST", "sys_test run over!", UVM_LOW)
           //phase.drop_objection(this);
       endtask
    endclass
 
    initial begin
       $timeformat(-9, 0, "ns", 5);
       run_test("sys_test");
    end
endmodule