How does forever behaves in fork block

In reply to sandy1664:

There are two processes created by the fork/join block - the two forever statements. label_1 is a statement label that is a part of the forever statement; label_1 is not a separate process. The disable statement just terminates the statement with the label_1. Terminating a statement means it jumps to the end of the statement. And since this statement is inside a forever statement, it repeats the statement forever.

You can wrap the two forever statements in begin/end blocks without changing the functionality.

fork 
  begin : process_1
    forever
    begin:label_1
      wait(flag1==1); 
      $display("flag1 asserted");
      #(duration);
      flag2 = 1;
    end
 end : process_1
 begin : process_2
  forever
    begin
      @(flag1);
      if(flag1==0)
        disable label_1;
    end
  end : process_2
join

But now the statement label process_1 encompasses an entire process, so disabling that statement will terminate the process.

P.S. You need to be careful using the disable label; statement. Statement labels are static identifiers and if the label is inside a task and there are multiple invocations of the task, disabling the label will disable all invocations of that label inside all tasks. SystemVerilog provides a variety of other mechanisms to terminate process that are more specific to the current process. (disable fork, process::kill)