目录
0.前言
可以用以下图来表示三者的区别:
1.fork...join
fork...join使内部所有线程同时开始运行,直到内部所有线程运行完毕后才跳出fork...join块儿。
下面我们以代码详细理解:
module test();
initial begin
$display("%t:AAAA",$time);//0
#10 $display("%t:BBBB",$time);//10
fork//10
$display("%t:CCCC",$time);10
#50 $display("%t:DDDD",$time);//10+50=60
#10 $display("%t:EEEE",$time);//10+10=20
begin//10,里面的线程顺序执行
#30 $display("%t:FFFF",$time);//10+30=40
#10 $display("%t:GGGG",$time);//40+10=50
end
join
$display("%t:HHHH",$time);//60
#80 $display("%t:IIII",$time);//60+80=140
end
endmodule
/*仿真结果:
0:AAAA
10:BBBB
10: CCCC
20: EEEE
40: FFFF
50: GGGG
60: DDDD
60: HHHH
140: IIII */
2.fork...join_any
fork...join_any使内部所有线程同时开始运行,只要有一个线程运行结束就跳出 fork...join_any块儿。
需要注意的是,当跳出 fork...join_any块儿后,里面的线程并行的和块儿外的线程运行
module test();
initial begin
$display("%t:AAAA",$time);//0
#10 $display("%t:BBBB",$time);//10
fork//10
$display("%t:CCCC",$time);//10,执行完该线程后跳出去
//后面的线程和块儿后的线程并行执行
#50 $display("%t:DDDD",$time);//10+50=60
#10 $display("%t:EEEE",$time);//10+10=20
begin//10,里面的线程顺序执行
#30 $display("%t:FFFF",$time);//10+30=40
#10 $display("%t:GGGG",$time);//40+10=50
end
join_any
$display("%t:HHHH",$time);//10
#80 $display("%t:IIII",$time);
end
endmodule
/*仿真结果:
0:AAAA
10:BBBB
10: CCCC
10: HHHH
20: EEEE
40: FFFF
50: GGGG
60: DDDD
140: IIII */
3.fork...join_none
fork...join_none运行开始后,里面的子线程并行的和块儿外的线程运行
module test();
initial begin
$display("%t:AAAA",$time);//0
#10 $display("%t:BBBB",$time);//10
fork//10
$display("%t:CCCC",$time);//10
#50 $display("%t:DDDD",$time);//10+50=60
#10 $display("%t:EEEE",$time);//10+10=20
begin//10,里面的线程顺序执行
#30 $display("%t:FFFF",$time);//10+30=40
#10 $display("%t:GGGG",$time);//40+10=50
end
join_none
$display("%t:HHHH",$time);//10
#20 $display("%t:IIII",$time);/10+20=30
end
endmodule
/*仿真结果:
0:AAAA
10:BBBB
10: HHHH
10: CCCC
20: EEEE
30: IIII
40: FFFF
50: GGGG
60: DDDD */
4.其它线程执行语句
4.1wait fork
该语句会等待前面的所有fork语句执行完毕后才会继续执行后面的语句:
module test();
initial begin
fork//0
#10 $display("%t:A",$time);//10
#20 $display("%t:B",$time);//0+20=20
join_any
fork//10
#5 $display("%t:C",$time);//10+5=15
#25 $display("%t:D",$time);//10+25=35
join_none
wait fork;
······
end
endmodule
/* 仿真结果:
10:A
15:C
20:B
35:D
······ */
4.2 disable fork
停止当前fork线程中未被执行的所有子线程,当然如果是fork...join_none后接disable fork,里面的线程会全部被杀掉。
module test();
initial begin
fork
#10 $display("%t:A",$time);
#20 $display("%t:B",$time);
#5 $display("%t:C",$time);//5,跳出
join_any
disable fork;//杀掉AB,继续执行D
#10 $display("%t:D",$time);//15
end
endmodule