SystemVerilog学习笔记(十):进程/细粒度进程控制

进程

进程或线程是作为独立实体执行的任何代码片段。fork-join块创建并行运行的不同线程。在下面的图-1中,可以看到进程的类型和进程控制。

序号进程描述
1.fork-join只有所有子线程执行完毕时,父线程才会执行。
2.fork-join_any只有任何一个子线程执行完毕时,父线程才会执行。
3.fork-join_none父线程与子线程并行执行。
4.wait fork使父线程等待所有子线程执行完毕。
5.disable fork当执行disable fork时,会终止所有子线程的执行。
6.细粒度进程控制这些用于控制进程,并提供进程/线程的状态。

 进程或线程

有3种类型的线程/进程

  1. fork-join
  2. fork-join_any
  3. fork-join_none 

fork-join

SystemVerilog通过fork-join结构支持并行线程。在fork-join进程中,只有当所有子线程完成执行时,父线程才会执行。

语法:-

fork  线程1  线程2  线程3
join

代码片段:-

$display("[%0t] Thread_T1: a的值为%0d,b的值为%0d,c的值为%0d,d的值为%0d",$time,a,b,c,d);fork:FORK_F1  begin:BEGIN_B2  #1 a <= b;  b <= 7;  $monitor("[%0t] Thread-T2: a的值为%0d,b的值为%0d,c的值为%0d,d的值为%0d",$time,a,b,c,d);  #1 ->e1;  c = b;  end:BEGIN_B2  begin:BEGIN_B3  wait(e1.triggered);  $display("[%0t] 事件已触发",$time);  begin:BEGIN_B4  #1 d = c;  end:BEGIN_B4  end:BEGIN_B3  join:FORK_F1 $display("[%0t] Thread_T3: a的值为%0d,b的值为%0d,c的值为%0d,d的值为%0d",$time,a,b,c,d); 

输出
在图-2中,我们可以看到Thread_T1首先在#0模拟时间执行,但是Thread_T3将在所有子线程执行完毕后才执行,子线程将根据时间延迟执行。

fork_join_output

在图-3中,可以清楚地了解关于fork-join代码的整个工作方式,以及与时间表区域相关的调度原理。

  • 变量的取样将在提前的区域中完成。
  • 所有阻塞赋值将在活动区域执行,所有非阻塞赋值将在活动区域中评估。
  • 事件将在活动区域执行。
  • $display语句将在活动区域执行。
  • 所有#0延迟语句将在非活动区域中执行。
  • 评估的非阻塞赋值将在NBA区域中执行。
  • $monitor语句将在推迟的区域中执行。

fork_join (1)

fork-join_any

当任何一个子线程完成执行时,父线程将执行。这意味着如果fork-join_any块中有2个或更多线程,并且每个线程需要不同的时间完成。在这种情况下,无论哪个线程先完成,fork-join_any都将退出该块,并开始执行模拟中的下一个父线程/语句。这并不意味着剩余的子线程将被模拟自动丢弃。这些线程将在后台运行。

语法:-

fork  Thread 1  Thread 2  Thread 3  
join_any  

代码片段:-

$display("[%0t] Thread_T1: Starting of fork_join_any",$time);a = "Kapu";
c = "Malpe";fork:FORK_F1  begin:BEGIN_B2  #0 $display("[%0t] Thread_T2: Values of a =%0s,b =%0s,c =%0s,d =%0s",$time,a,b,c,d);  begin:BEGIN_B3  b <= a;  #1 $display("[%0t] Thread_T3: Values of a =%0s,b =%0s,c =%0s,d =%0s",$time,a,b,c,d);  end:BEGIN_B3  end:BEGIN_B2  fork:FORK_F2  begin:BEGIN_B4  #3 -> e1;  $display("[%0t] Thread_T4: Values of a =%0s,b =%0s,c =%0s,d =%0s",$time,a,b,c,d);  end:BEGIN_B4  join:FORK_F2  join_any:FORK_F1#1 $display("[%0t] Thread_T5: Values of a =%0s,b =%0s,c =%0s,d =%0s",$time,a,b,c,d);begin:BEGIN_B5wait(e1.triggered);d = "Kodi";$monitor("[%0t] Thread_T6: Values of a =%0s,b =%0s,c =%0s,d =%0s",$time,a,b,c,d);
end:BEGIN_B5

输出:-
在下图中,我们可以看到父线程Thread_T1在#0处执行,子线程Thread_T3在#1处执行,然后只有父线程Thread_T5将在#2处执行。

Untitled Diagram drawio (23)

fork join_any

fork-join_none

父线程与子线程并行执行。这意味着在fork-join_none外部的线程不会等待fork-join_none内部的任何线程完成,它们只是并行执行。这并不意味着模拟会自动丢弃其余的子线程。这些线程将在后台运行。

语法:-

fork Thread 1  Thread 2  Thread 3  
join_none 

代码片段:-

$display("[%0t] Thread_T1: Starting of fork_join_none",$time);a = "Kapu";
c = "Malpe";fork:FORK_F1  begin:BEGIN_B2  #1 $display("[%0t] Thread_T2: Values of a =%0s,b =%0s,c =%0s,d =%0s",$time,a,b,c,d);      b <= a;  #1 $display("[%0t] Thread_T3: Values of a =%0s,b =%0s,c =%0s,d =%0s",$time,a,b,c,d);  end:BEGIN_B2  fork:FORK_F2  #1 -> e1;  $display("[%0t] Thread_T4: Values of a =%0s,b =%0s,c =%0s,d =%0s",$time,a,b,c,d);  join:FORK_F2  join_none:FORK_F1#1 $display("[%0t] Thread_T5: Values of a =%0s,b =%0s,c =%0s,d =%0s",$time,a,b,c,d);wait(e1.triggered);
d = "Kodi";$monitor("[%0t] Thread_T6: Values of a =%0s,b =%0s,c =%0s,d =%0s",$time,a,b,c,d);

输出:在下图中,在#0处执行父线程Thread_T1和子线程Thread_T4,然后在#1处同时执行父线程Thread_T5和子线程Thread_T2,以此类推。

Untitled Diagram drawio (28)

fork_join_none


进程控制

System Verilog提供了允许一个进程终止或等待其他进程完成的构造。

  1. wait fork
  2. disable fork
  3. 细粒度进程控制

wait fork

wait fork语句用于确保所有子进程(由调用进程创建的进程)都已完成执行。它将等待直到所有fork进程完成执行。

代码片段:-

#1 $display("[%0t] Thread_T1: values of a = %0s,b = %0s,c = %0s",$time,a,b,c);fork:FORK_F1  #2 b <= "Delta";  #0 $display("[%0t] Thread_T2: values of a = %0s,b = %0s,c = %0s",$time,a,b,c);  begin:BEGIN_B2  #1 -> e1;  c = "Hoode";  #1 $display("[%0t] Thread_T3: values of a = %0s,b = %0s,c = %0s",$time,a,b,c);  end:BEGIN_B2  fork:FORK_F2  wait(e1.triggered);  #2 $display("[%0t] Thread_T4: values of a = %0s,b = %0s,c = %0s",$time,a,b,c);  join:FORK_F2  #1 $display("[%0t] Thread_T5: values of a = %0s,b = %0s,c = %0s",$time,a,b,c);  join_none:FORK_F1  wait fork;  
#0 $monitor("[%0t] Thread_T6: values of a = %0s,b = %0s,c = %0s",$time,a,b,c);  

输出:-

在下图中,我们看到在#1处,父线程Thread_T1将被执行,并且有一个#0语句将在非活动区域中工作,语句将在相应区域中执行。尽管我们使用了fork-join_none,但$monitor语句将等待所有子线程被执行。

wait_fork

disable fork

执行disable fork时,所有活动的进程都将被终止。

代码片段:-

#0 $display("[%0t] Thread_T1: Values of a = %0s,b = %0s,c = %0s",$time,a,b,c);fork:FORK_F1  #3 b <= "Delta";  #4 $display("[%0t] Thread_T2: Values of a = %0s,b = %0s,c = %0s",$time,a,b,c);  begin:BEGIN_B2  #1 -> e1;  c = "Hoode";  #1 $display("[%0t] Thread_T3: Values of a = %0s,b = %0s,c = %0s",$time,a,b,c);  end:BEGIN_B2  fork:FORK_F2  @(e1.triggered);  #1 $display("[%0t] Thread_T4: Values of a = %0s,b = %0s,c = %0s",$time,a,b,c);  join:FORK_F2  #1 $display("[%0t] Thread_T5: Values of a = %0s,b = %0s,c = %0s",$time,a,b,c);  join_any:FORK_F1  disable fork;  
#1 $display("[%0t] Thread_T6: ending of fork-join",$time);   

输出:-

在下图中,在#0处,我们正在等待事件被触发,#0语句将在活动区域中执行,因为它是$display语句。 在#1处,它正在触发事件e1,并且一个子线程Thread_T5将被执行,然后由于使用了fork-join_any,它将转到父线程并触发disable fork语句,然后所有剩余的子线程将被终止。

细粒度进程控制 

SystemVerilog有一个内置的名为Process的类,允许一个进程(例如,像fork_join)访问和控制进程/线程。当我们分叉出任何线程时,会在那时创建Process类的新对象。该对象包含有关该线程的状态信息。

Untitled Diagram drawio (5)

序号任务描述
1.self()用于创建进程的ID/对象。
2.status()用于返回当前线程的模式。
3.kill()用于终止线程。
4.await()用于等待当前线程完成其他线程。
5.suspend()用于暂停线程一段时间。
6.resume()用于从暂停状态恢复线程。

self()

它为Process类创建对象/ID。该对象用于访问Process类的所有预定义方法。对象包含所有线程的状态信息。

语法:-

process p_handle1,p_handle2;  
initial begin p_handle1 = process :: self();  p_handle2 = process :: self(); 
end  

代码片段:-

fork:FORK_F1  $display("[%0t] Entered into fork-join and started first check for the process",$time);  #1 ->e1;  begin:BEGIN_B2  wait(e1.triggered);  if(p1 == null)  $display("[%0t] Not created",$time);  else  $display("[%0t] Created",$time);  ->e3;  #1 ->e2;  end:BEGIN_B2  #2 p1 = process :: self();  begin:BEGIN_B3  wait(e2.triggered);$display("[%0t] Started second check for the process",$time);  if(p1 == null)$display("[%0t] Not created",$time);else$display("[%0t] Created",$time);->e4;end:BEGIN_B3fork:FORK_F2begin:BEGIN_B4wait(e3.triggered);$display("[%0t] first check for the process done",$time);end:BEGIN_B4begin:BEGIN_B5wait(e4.triggered);$display("[%0t] Second check for the process done",$time);end:BEGIN_B5join:FORK_F2join:FORK_F1

在上面的代码片段中,您可以看到在#0模拟时间时声明了进程类的句柄。在下面的图中,

  • 在#1模拟时间时,我们正在检查是否创建了对象p1,然后它显示“未创建”。
  • 在#2模拟时间时,我们为进程p1创建一个对象。
  • 在#3模拟时间时,我们检查对象p1,显示“已创建”。

fine_self_output

fork join_any _self _kill-Page-2 drawio (3)

Status()

它将显示进程ID的状态/模式。有不同的模式,如已完成(Finished)、运行中(Running)、等待中(Waiting)、已挂起(Suspended)、已终止(Killed)。

语法:-

process p_handle;
initial beginbegin  p_handle = process :: self();  $display("status : %s",p_handle.status());  end
end 

代码片段:-

$display("[%0t] Seeking status:",$time);  fork:FORK_F1  begin:BEGIN_B2  p1 = process :: self();  #1 $display("[%0t] I am in process p1",$time);  $display("[%0t] Initial status of p1: %s",$time,p1.status());  #1 $display("[%0t] Still working in p1",$time);  ->e1;  ->e2;  end:BEGIN_B2  begin:BEGIN_B3  p2 = process :: self();  wait(e2.triggered);  #1 $display("[%0t] I am in process p2",$time);  $display("[%0t] Initial status of p2: %s",$time,p2.status());  $display("[%0t] Still working in p2",$time);  ->e3;  end:BEGIN_B3  begin:BEGIN_B4  wait(e1.triggered);  $display("[%0t] Final status of p1: %s",$time,p1.status());  end:BEGIN_B4  begin:BEGIN_B5  wait(e3.triggered);  $display("[%0t] Final status of p2: %s",$time,p2.status());  end:BEGIN_B5  fork:FORK_F2  p3 = process :: self();  #1 $display("[%0t] I am in process p3",$time);  #1 $display("[%0t] status of p3: %s",$time,p3.status());  #1 ->e4;  join:FORK_F2  join_any:FORK_F1  wait(e4.triggered);  
#1 $display("[%0t] Final status of p3: %s",$time,p3.status());  

在下图中,

  • 您可以看到一些字符串是大写的,这些是进程p1和p2的状态。
  • 在不同的模拟时间,进程/线程的状态将根据它们的执行而改变。

    fine_status_output

status drawio (1)

kill()

kill()函数终止进程及其所有子进程。如果进程没有被阻塞(由于等待语句、延迟或等待事件触发),则它将在当前时间戳被终止。

语法:-

Process p_handle1; 
initial begin fork p_handle1 = process :: self();  p_handle1.kill(); join_any  
end 

代码片段:-

$display("[%0t] Seeking status:",$time);fork:FORK_F1  begin:BEGIN_B2  p1 = process :: self();  #1 $display("[%0t] I am in process p1",$time);  $display("[%0t] Initial status check of p1: %s",$time,p1.status);  ->e1;  if(p1.status() != process :: FINISHED)  p1.kill();  $display("hi i am working");  $display("what about you?");  end:BEGIN_B2  begin:BEGIN_B3  wait(e1.triggered);  #1 $display("[%0t] Status of p1 before killing: %s",$time,p1.status());  end:BEGIN_B3  join:FORK_F1  

在上述代码片段中,您可以看到在#0模拟时间时创建了进程p1的进程类对象。 在下图中,

  • 在#1模拟时间时,进程p1的状态为RUNNING
  • 在使用kill()方法后的#2模拟时间时,进程p1的状态为KILLED

fine_kill_output

fork join_any _self _kill-Page-3 drawio

await()

这种方法用于允许一个进程等待另一个进程/线程完成。

语法:-

Process p_handle1,p_handle2;  
initial begin  fork beginp_handle1 = process :: self(); p_handle2.await(); end begin p_handle2 = process :: self();endjoin 
end

代码片段:-

在上述代码片段中,我们试图使进程p1等待直到进程p2完成。 在下面的图8中,您可以看到:

  • 在#1模拟时间之前使用await()方法之前,p1的状态为RUNNING
  • 在使用await()方法后的#2模拟时间时,p1的状态为WAITING
  • 一旦p2的状态为FINISHED,则p1的状态也为FINISHED

fine_await_output

await drawio

suspend()

这个方法用于暂停进程/线程的执行。它可以暂停自己或其他进程的执行。执行将暂停,直到遇到resume()方法。 如果进程没有被阻塞(由于等待语句、延迟或等待事件触发),则它将在当前时间戳被暂停。

语法:-

Process p_handle1;  
initial begin  fork beginp_handle1 = process :: self();p_handle1.suspend();  endjoin_none 
end 

代码片段:-

在上述代码片段中,我们试图使进程p1永久暂停。 在下面的图10中,您可以看到:

  • 在#1模拟时间之前,暂停p1的状态为RUNNING
  • 在#3模拟时间之后,暂停p1的状态为SUSPENDED

fine_suspend_output

Untitled Diagram drawio (5)

resume()

这个方法用于重新启动被暂停的进程。如果暂停的进程在被阻塞时(由于等待语句、延迟或等待事件触发),则恢复该进程将重新初始化到事件表达式或等待条件为真,或等待延迟到期。

语法:-

Process p_handle1,p_handle2;
initial begin fork  begin  p_handle1 = process :: self();  p_handle1.suspend();  end  begin p_handle2 = process :: self();p_handle1.resume();  end  join_none  
end

代码片段:-

$display("[%0t] Seeking status:",$time);  fork:FORK_F1  begin:BEGIN_B2  p1 = process :: self();  #1 $display("[%0t] I am in process p1",$time);  $display("[%0t] Initial status of p1: %s",$time,p1.status());  ->e1;  if(p1.status() != process :: FINISHED)  begin:BEGIN_B3  #1 $display("[%0t] Status of p1 before suspending: %s",$time,p1.status());  p1.suspend();  $display("[%0t] Status of p2 in p1 block: %s",$time,p2.status());  end:BEGIN_B3  end:BEGIN_B2  begin:BEGIN_B4  wait(e2.triggered);  $display("[%0t] Status of p1 before resuming: %s",$time,p1.status());  p1.resume();  #1 $display("[%0t] Status of p1 after resuming: %s",$time,p1.status());  ->e3;  end:BEGIN_B4  begin:BEGIN_B6  p2 = process :: self();  #1 $display("[%0t] I am in process p2",$time);  $display("[%0t] Initial status of p2: %s",$time,p2.status());  if(p1.status() == process :: SUSPENDED)  #1 ->e2;  end:BEGIN_B6  begin:BEGIN_B7  wait(e3.triggered);  #1 $display("[%0t] Final status of p1: %s",$time,p1.status());  $display("[%0t] Final status of p2: %s",$time,p2.status());  end:BEGIN_B7  join:FORK_F1

在上述代码片段中,我们试图在进程p2中恢复进程p1。 在下面的图12中,您可以看到:

  • 在#1模拟时间时,p1的状态为RUNNING
  • 在使用resume()方法之前的#2模拟时间时,p1的状态为SUSPENDED
  • 在使用resume()方法后的#3模拟时间时,p1的状态为FINISHED

fine_resume_output

resume drawio

进程常见问题 

  • fork_join、fork_join_any 和 fork_join_none 之间的区别
fork_joinfork_join_anyfok_join_none
在 fork_join 中,主(父)线程在 fork_join 中的所有线程(子线程)执行完毕后才会执行在 fork_join_any 中,如果任何一个子线程执行,则主(父)线程执行在 fork_join_none 中,子线程和主(父)线程同时执行
  • 我们可以在 fork_join 中使用 wait_fork 吗?

我们知道,在 fork_join 中,仅当 fork_join 中的所有线程执行完毕时,主线程才会执行,因此不需要使用 wait_fork。 我们可以在 fork_join_any 或 fork_join_none 语句后使用 wait fork,以等待 fork-join_any 或 fork_join_none 中的所有线程完成。 因此,在 fork_join 中不需要 wait_fork。

  • 阻塞和非阻塞赋值的区别
阻塞非阻塞
在阻塞赋值中,一条语句执行完毕后,下一条语句将执行,即右侧表达式的第一个表达式被评估并立即分配给左侧变量在非阻塞赋值中,对当前时间单位的所有右侧表达式进行评估,并在时间单位结束时分配给左侧变量
由 " = " 表示由 " <= " 表示
它按顺序执行它并行执行
阻塞用于组合逻辑非阻塞用于时序逻辑
  • wait event 和 @ event 之间的区别

如果我们在相同的延迟下触发 wait 和 @,那么 wait 语句会被执行,因为 wait 捕获速度比 @ 快。

  • 我们可以使用不同延迟执行 wait 和 @ 吗?
module tb;    event e;  initial begin  #20 ->e;  $display($time,"thread1");  end  initial   begin  #25 @e;  $display($time,"thread2");  end  initial   begin  #15 wait(e.triggered);  $display($time,"thread3");  end 
endmodule  

在上面的例子中,我们可以看到事件、wait 和 @ 的延迟是不同的。我们还可以看到这里 @ 的延迟大于事件的延迟,而 wait 的延迟小于事件的延迟,所以这里只有 wait 语句与事件的延迟一起执行。因此,在下面的图中,我们可以看到线程 1 和线程 3 使用相同的延迟(#20)执行。

Untitled Diagram drawio (7)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/60700.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

javascript用来干嘛的?赋予网站灵魂的语言

javascript用来干嘛的&#xff1f;赋予网站灵魂的语言 在互联网世界中&#xff0c;你所浏览的每一个网页&#xff0c;背后都有一群默默工作的代码在支撑着。而其中&#xff0c;JavaScript就像是一位技艺精湛的魔术师&#xff0c;它赋予了网页生命力&#xff0c;让原本静态的页…

Golang | Leetcode Golang题解之第553题最优除法

题目&#xff1a; 题解&#xff1a; func optimalDivision(nums []int) string {n : len(nums)if n 1 {return strconv.Itoa(nums[0])}if n 2 {return fmt.Sprintf("%d/%d", nums[0], nums[1])}ans : &strings.Builder{}ans.WriteString(fmt.Sprintf("%d…

宝塔 docker 部署onlyoffice 服务

1.宝塔安装docker,直接下载安装就行 2.docker拉取onlyoffice镜像 docker pull onlyoffice/documentserver:5.3.1.26 5.4或更高的版本已经解决了连接数限制方法的Bug 3.创建容器 docker run -d --name onlyoffice --restartalways -p 暴露端口号:80 onlyoffice/documentserv…

InternVL 多模态模型部署微调实践

目录 0 什么是MLLM 1 开发机创建与使用 2 LMDeploy部署 2.1 环境配置 2.2 LMDeploy基本用法介绍 2.3 网页应用部署体验 3 XTuner微调实践 3.1 环境配置 3.2.配置文件参数解读 3.3 开始微调 4.体验模型美食鉴赏能力 0 什么是MLLM 多模态大语言模型 ( Multimodal Larg…

pgSQL-timescaledb复制表出现的问题

今日在工作中&#xff0c;需要复制一张timescaledb表&#xff0c;pgAdmin上复制一直未成功&#xff0c;或者我找错位置了。 1.我使用Navicate连接pgSQL&#xff0c;连上后选中相应表&#xff0c;右键复制结构即可 2.复制结构后&#xff0c;到pgAdmin中&#xff0c;将对应表下的…

Docker:技术架构的演进之路

前言 技术架构是指在软件开发和系统构建中&#xff0c;为了满足业务需求和技术要求&#xff0c;对系统的整体结构、组件、接口、数据流以及技术选型等方面进行的详细设计和规划。它是软件开发过程中的重要组成部分&#xff0c;为开发团队提供了明确的指导和规范&#xff0c;确…

A029-基于Spring Boot的物流管理系统的设计与实现

&#x1f64a;作者简介&#xff1a;在校研究生&#xff0c;拥有计算机专业的研究生开发团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339; 赠送计算机毕业设计600…

【flutter】flutter2升级到3.

文章目录 背景flutter2-3升级的修改之处界面效果其它 背景 以这个 https://github.com/aa286211636/Flutter_QQ 为例子&#xff0c; 升级下看看 flutter2-3升级的修改之处 flatButton变为TextButton设备屏幕尺寸获取: Screen.width(context)变为MediaQuery.of(context).size…

自由学习记录(21)

感觉反而 还复杂一点&#xff0c;关系并不纯粹&#xff0c;游戏里用的少...的确 是知道为什么游戏不用了 理解思想就可以了&#xff0c;实际操作也是动态的分析&#xff0c;硬套某种模式也不是怎么很合适 MVC的了解应该是差不多了&#xff0c;重点还是实际中的使用了 所以删了…

力扣-Mysql-3322- 英超积分榜排名 III(中等)

一、题目来源 3322. 英超积分榜排名 III - 力扣&#xff08;LeetCode&#xff09; 二、数据表结构 表&#xff1a;SeasonStats --------------------------- | Column Name | Type | --------------------------- | season_id | int | | team_id …

2023年高校大数据挑战赛A题中文文本纠错求解全过程文档及程序

2023年高校大数据挑战赛 A题 中文文本纠错 原题再现&#xff1a; 中文文本纠错的任务主要是针对中文文本中出现的错误进行检测和纠正&#xff0c;属于人工智能自然语言处理的研究子方向。中文文本纠错通常使用的场景有政务公文、裁判文书、新闻出版等&#xff0c;中文文本纠错…

catchadmin-webman 宝塔 部署

1&#xff1a;宝塔的php 中删除禁用函数 putenv 问题&#xff1a; 按照文档部署的时候linux&#xff08;php&#xff09; vue (本地) 无法访问后端api/login 的接口 。 解决办法&#xff1a; webman 没有配置nginx 反向代理 配置就能正常访问了

力扣515:在每个树行中找最大值

给定一棵二叉树的根节点 root &#xff0c;请找出该二叉树中每一层的最大值。 示例1&#xff1a; 输入: root [1,3,2,5,3,null,9] 输出: [1,3,9]示例2&#xff1a; 输入: root [1,2,3] 输出: [1,3]提示&#xff1a; 二叉树的节点个数的范围是 [0,104]-231 < Node.val &l…

<项目代码>YOLOv8 番茄识别<目标检测>

YOLOv8是一种单阶段&#xff08;one-stage&#xff09;检测算法&#xff0c;它将目标检测问题转化为一个回归问题&#xff0c;能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法&#xff08;如Faster R-CNN&#xff09;&#xff0c;YOLOv8具有更高的…

__VUE_PROD_HYDRATION_MISMATCH_DETAILS__ is not explicitly defined

VUE_PROD_HYDRATION_MISMATCH_DETAILS 未明确定义。您正在运行 Vue 的 esm-bundler 构建&#xff0c;它期望这些编译时功能标志通过捆绑器配置全局注入&#xff0c;以便在生产捆绑包中获得更好的tree-shaking优化。 Vue.js应用程序正在使用ESM&#xff08;ECMAScript模块&#…

《FreeRTOS列表和列表项篇》

FreeRTOS列表和列表项 1. 什么是列表和列表项&#xff1f;1.1 列表list1.2 列表项list item 2. 列表和列表项的初始化2.1 列表的初始化2.2 列表项的初始化 3. 列表项的插入4. 列表项末尾插入5. 列表项的删除6. 列表的遍历 列表和列表项是FreeRTOS的一个数据结构&#xff0c;是F…

MySQL进阶-索引的组合索引

练习题目 题目链接难度SQL进阶-索引的组合索引★★★☆☆ SQL思路 SQL进阶-索引的组合索引 初始化数据 drop table if exists user_profile; CREATE TABLE user_profile ( id int NOT NULL, device_id int NOT NULL, gender varchar(14) NOT NULL, age int , university va…

【iStat Menus for MacBook状态栏菜单系统监控工具--安装教程【简单操作,随时了解电脑情况】

Mac分享吧 文章目录 iStat Menus for MacBook状态栏菜单系统监控软件 效果图展示一、iStat Menus 状态栏菜单系统监控软件 Mac电脑版——v6.73(1240)1️⃣&#xff1a;下载软件2️⃣&#xff1a;安装软件3️⃣&#xff1a;软件自定义配置 安装完成&#xff01;&#xff01;&am…

netmap.js:基于浏览器的网络发现工具

netmap.js是一款基于浏览器&#xff0c;用于提供主机发现和端口扫描功能的网络发现工具。 netmap.js的执行速度也非常的快&#xff0c;由于其使用了es6-promise-pool&#xff0c;因此它可以有效地运行浏览器允许的最大并发连接数。 动机 由于我正需要一个基于浏览器的端口扫…

计算机网络 (2)计算机网络的类别

计算机网络的类别繁多&#xff0c;根据不同的分类原则&#xff0c;可以得到各种不同类型的计算机网络。 一、按覆盖范围分类 局域网&#xff08;LAN&#xff09;&#xff1a; 定义&#xff1a;局域网是一种在小区域内使用的&#xff0c;由多台计算机组成的网络。覆盖范围&#…