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_B5
   wait(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_B3
      
   fork:FORK_F2

      begin:BEGIN_B4
         wait(e3.triggered);
         $display("[%0t] first check for the process done",$time);
      end:BEGIN_B4

      begin:BEGIN_B5
         wait(e4.triggered);
         $display("[%0t] Second check for the process done",$time);
      end:BEGIN_B5
      
   join:FORK_F2

join: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 begin
   begin  
      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 
      begin
         p_handle1 = process :: self(); 
         p_handle2.await(); 
      end 
      begin 
         p_handle2 = process :: self();
      end
   join 
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 
      begin
         p_handle1 = process :: self();
         p_handle1.suspend();  
      end
   join_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)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Visual Studio系列教程】如何在 VS 上编程?

上一篇博客中&#xff0c;我们介绍了《什么是 Visual Studio&#xff1f;》。本文&#xff0c;我们来看第2篇《如何在 VS 上编程&#xff1f;》。阅读本文大约10 分钟。我们会向文件中添加代码&#xff0c;了解 Visual Studio 编写、导航和了解代码的简便方法。 本文假定&…

【3D Slicer】的小白入门使用指南八

3D Slicer DMRI(Diffusion MRI)-扩散磁共振认识和使用 0、简介 大脑解剖 ● 白质约占大脑的 45% ● 有髓神经纤维(大约10微米轴突直径) 白质探索 朱尔斯约瑟夫德杰林(Jules Joseph Dejerine,《神经中心解剖学》(巴黎,1890-1901):基于髓磷脂染色标本的神经解剖图谱)…

GraphPad Prism与鹰谷电子实验记录本强强联合,数据兼容互通

在科研探索的征途上&#xff0c;每一次数据的记录与分析都至关重要。鹰谷很高兴地宣布&#xff0c;鹰谷电子实验记录本InELN&#xff0c;与国际知名生物数据统计分析GraphPad Prism软件&#xff0c;实现数据快速兼容互通&#xff01;使用鹰谷电子实验记录本的用户&#xff0c;将…

HarmonyOS的@State装饰器的底层实现

HarmonyOS的State装饰器的底层实现 序言准备工作实现State装饰器 序言 ArkTS是鸿蒙生态的应用开发语言。它在保持TypeScript&#xff08;简称TS&#xff09;基本语法风格的基础上&#xff0c;进一步通过规范强化静态检查和分析&#xff0c;使得在程序运行之前的开发期能检测更…

实战:深入探讨 MySQL 和 SQL Server 全文索引的使用及其弊端

在数据库中处理大量文本数据时,包含搜索(例如查找包含特定单词的文本)往往是必需的。然而,直接使用 LIKE %text% 的方式在大数据量中进行模糊查询会造成性能瓶颈。为了解决这一问题,MySQL 和 SQL Server 提供了全文索引(Full-Text Indexing)功能,可以显著加速文本数据的…

shell 100例

1、每天写一个文件 (题目要求&#xff09; 请按照这样的日期格式(xxxx-xx-xx每日生成一个文件 例如生成的文件为2017-12-20.log&#xff0c;并且把磁盘的使用情况写到到这个文件中不用考虑cron&#xff0c;仅仅写脚本即可 [核心要点] date命令用法 df命令 知识补充&#xff1…

网络管理之---3种网络模式配置

目标&#xff1a; 了解几个概念&#xff1a; 1.什么是IP&#xff1f;什么是IP地址&#xff1f; 2.什么是桥接、NAT、仅主机模式 3.端口&#xff1f; 4.什么是网络接口命名规则 5.网络管理器 IP&#xff1a;指网络之间互联的协议&#xff0c;是TCP/IP 体系中的网络协议 I…

ubuntu 下mosquitto TLS配置

1、/etc/mosquitto/mosquitto.conf文件配置 persistence true persistence_location /var/lib/mosquitto/ log_dest file /var/log/mosquitto/mosquitto.log include_dir /etc/mosquitto/conf.d listener 1883 listener 8883 0.0.0.0 password_file /etc/mosquitto/pwfile cert…

zabbix搭建钉钉告警流程

目录 &#x1f324;️zabbix实验规划 &#x1f324;️zabbix实验步骤 &#x1f4d1;1 使用钉钉添加一个自定义的机器人 ​ &#x1f4d1;2在zabbix-server上编写钉钉信息发送脚本&#xff0c;设置钉钉报警媒介 ☁️ 设置钉钉报警媒介​编辑​编辑 ☁️在添加消息模板​编辑​…

【JavaWeb】JavaWeb入门之XML详解

目录 1.XML介绍 1.1.XML概述 1.1.1.什么是XML 1.1.2.XML的作用 1.1.3.XML与HTML的比较 1.1.4.XML和properties&#xff08;属性文件&#xff09;比较 1.1.5.W3C组织 1.2.XML语法概述 1.2.1.XML文档展示 1.2.2.XML文档的组成部分 1.3.XML文档声明 1.3.1.什么是XML文…

基于Zynq FPGA对雷龙SD NAND的测试

一、SD NAND特征 1.1 SD卡简介 雷龙的SD NAND有很多型号&#xff0c;在测试中使用的是CSNP4GCR01-AMW与CSNP32GCR01-AOW。芯片是基于NAND FLASH和 SD控制器实现的SD卡。具有强大的坏块管理和纠错功能&#xff0c;并且在意外掉电的情况下同样能保证数据的安全。 其特点如下&…

<Project-23 Navigator Portal> Python flask web 网站导航应用 可编辑界面:添加图片、URL、描述、位置移动

目的&#xff1a; 浏览器的地址簿太厚&#xff0c;如下图&#xff1a; 开始&#xff0c;想给每个 Web 应用加 icon 来提高辨识度&#xff0c;发现很麻烦&#xff1a;create image, resize, 还要挑来挑去&#xff0c;重复性地添加代码。再看着这些密密麻麻的含有重复与有规则的…

【Kafka】集成案例:与Spark大数据组件的协同应用

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《大数据前沿&#xff1a;技术与应用并进》&#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、什么是kafka 2、Kafka 的主要特性 3、Kafka 的…

Windows上安装专业版IDEA2024并激活

1、IDEA官方下载 搜索IDEA官网点击进入&#xff0c;点击Download&#xff08;目前这个激活脚本只能激活2024.1.7&#xff0c;2024.2.x的版本都不能激活&#xff0c;2024.1.7版本已上传资源&#xff09;&#xff0c;如图&#xff1a; 2、开始安装 1&#xff09;、双击下载的.…

CSS教程(二)- CSS选择器

1. 作用 匹配文档中的某些元素为其应用样式。根据不同需求把不同的标签选出来。 2. 分类 分类 基础选择器 包含 标签选择器、ID选择器、类选择器、通用选择器等 复合选择器 包含 后代选择器、子代选择器、伪类选择器等 1 标签选择器 介绍 又称为元素选择器&#xff0c;根…

Unix进程

文章目录 命令行参数进程终止正常结束异常终止exit和_exitatexit 环境变量环境变量性质环境表shell中操作环境变量查看环境变量设置环境变量 环境变量接口获取环境变量设置环境变量 环境变量的继承性 进程资源shell命令查看进程的资源限制 进程关系进程标识进程组会话控制终端控…

c# onnx 调用yolo v11进行目标检测

先上图&#xff0c;支持图片&#xff0c;视频检测 FormYoloV11.cs using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using OpenCvSharp; using OpenCvSharp.Dnn; using System; using System.Collections.Generic; using System.Diagnostics; usin…

【多语言】每种语言打印helloworld,编译为exe会占多大空间

文章目录 背景c语言 53KBc 53KBgo 1.8Mdart 4.6Mpython未测试nodejs未测试rust未测试java未测试cmd || bash || powershell 未测试other 背景 各个版本的helloworld&#xff0c;纯属闲的, 环境如下: - win10 - mingw: gcc8.1.0 - go1.21 - dart3.5.4c语言 53KB gcc main.c -…

前端搭建低代码平台,微前端如何选型?

目录 背景 一、微前端是什么&#xff1f; 二、三大特性 三、现有微前端解决方案 1、iframe 2、Web Components 3、ESM 4、EMP 5、Fronts 6、无界&#xff08;文档&#xff09; 7、qiankun 四、我们选择的方案 引入qiankun并使用&#xff08;src外层作为主应用&#xff09; 主应…

CVE-2024-2961漏洞的简单学习

简单介绍 PHP利用glibc iconv()中的一个缓冲区溢出漏洞&#xff0c;实现将文件读取提升为任意命令执行漏洞 在php读取文件的时候可以使用 php://filter伪协议利用 iconv 函数, 从而可以利用该漏洞进行 RCE 漏洞的利用场景 PHP的所有标准文件读取操作都受到了影响&#xff1…