mormot.core.threads--TSynBackgroundThreadMethod

news/2024/7/20 5:36:26/文章来源:https://www.cnblogs.com/hieroly/p/18289859

mormot.core.threads--TSynBackgroundThread

在mORMot 2框架中,TSynBackgroundThreadEventTSynBackgroundThreadMethodTSynBackgroundThreadProcedureTSynBackgroundThreadProcessTSynBackgroundTimer这几个类虽然都涉及到后台线程的执行,但它们各自有不同的用途和设计目标。以下是对这些类之间差异的概述:

  1. TSynBackgroundThreadEvent

    • 这个类可能设计用于执行与事件相关的回调函数。它可能封装了一个事件处理机制,允许您在后台线程中响应特定的事件。
    • 回调函数的签名可能包括一个事件发送者(Sender)参数,以及可能的其他参数,用于传递事件相关的数据。
    • 由于名称中包含“Event”,它可能特别适用于事件驱动的场景。
  2. TSynBackgroundThreadMethod

    • 这个类设计用于执行标准的TThreadMethod类型的回调,即无参数且返回Void的过程。
    • 它提供了一种在后台线程中执行这些回调的简便方式,使得与Delphi标准线程库兼容的代码可以轻松地与mORMot 2框架集成。
    • 由于TThreadMethod是Delphi中用于线程方法的标准类型,因此这个类可能特别适用于需要这种兼容性的场景。
  3. TSynBackgroundThreadProcedure

    • 这个类可能设计用于执行简单的无参数过程(procedure)回调,而不是一个对象方法或 TThreadMethod
    • 它与TSynBackgroundThreadMethod类似,但可能更加专注于那些不需要传递额外参数的过程。
    • 使用这个类可以使代码更加简洁,特别是当回调不需要访问任何外部状态或参数时。
  4. TSynBackgroundThreadProcess

    • 这个类可能是一个更通用的后台线程处理类,它可能提供了执行周期性任务或长时间运行任务的能力。
    • 它可能封装了线程创建、启动、暂停、恢复和终止的逻辑,以及任务调度的机制。
    • 与其他几个类相比,TSynBackgroundThreadProcess可能更加灵活和强大,适用于需要复杂任务调度的场景。
  5. TSynBackgroundTimer

    • 这个类专门设计用于在后台线程中执行定时任务。
    • 它可能内部维护了一个或多个定时器,允许您安排任务在指定的时间间隔后执行。
    • TSynBackgroundTimer可能还提供了向定时任务传递消息或参数的能力,以及查询任务状态和执行结果的方法。
    • 它特别适用于需要定时执行任务的场景,如心跳检测、定时轮询等。

上述描述是基于对类名的一般性推断和假设。实际上,mORMot 2框架中的这些类的具体实现和用途可能有所不同。因此,如果您正在使用mORMot 2框架,并且想要了解这些类的确切差异和用法,最好的做法是查阅mORMot 2的官方文档或源代码。这将为您提供关于这些类的详细信息和示例代码,帮助您更好地理解和使用它们。

TSynBackgroundThreadMethodAbstrac 定义

/// TSynBackgroundThreadAbstract 进程的状态机状态
TSynBackgroundThreadProcessStep = (flagIdle,           // 空闲状态flagStarted,        // 已启动状态flagFinished,       // 已完成状态flagDestroying);    // 正在销毁状态/// TSynBackgroundThreadAbstract进程的状态机状态集合
TSynBackgroundThreadProcessSteps = set of TSynBackgroundThreadProcessStep;/// 抽象TThread类,能够在其自己的执行内容中运行一个方法
// - 典型用途是作为处理数据或远程访问的后台线程,
// 同时UI通过循环运行OnIdle事件保持响应:
// 例如,查看mormot.rest.client.pas单元中TRestClientUri.OnIdle是如何处理此事件的
// - 您不应直接使用此类,而应继承它并重写Process方法,
// 或者使用TSynBackgroundThreadEvent/TSynBackgroundThreadMethod,
// 并提供一个更加方便的回调函数
TSynBackgroundThreadMethodAbstract = class(TSynBackgroundThreadAbstract)
protectedfPendingProcessLock: TLightLock; // 对fPendingProcessFlag的原子访问fCallerEvent: TSynEvent;         // 调用者事件fParam: pointer;                 // 参数指针fCallerThreadID: TThreadID;      // 调用者线程IDfBackgroundException: Exception; // 后台线程异常fOnIdle: TOnIdleSynBackgroundThread; // 空闲时回调事件fOnBeforeProcess: TOnNotifyThread;    // 处理前通知回调fOnAfterProcess: TOnNotifyThread;     // 处理后通知回调fPendingProcessFlag: TSynBackgroundThreadProcessStep; // 待处理标志procedure ExecuteLoop; override; // 重写执行循环function OnIdleProcessNotify(var start: Int64): Int64; // 空闲处理通知,返回已用毫秒数function GetOnIdleBackgroundThreadActive: boolean; // 获取OnIdle事件是否激活function GetPendingProcess: TSynBackgroundThreadProcessStep; // 获取待处理状态procedure SetPendingProcess(State: TSynBackgroundThreadProcessStep); // 设置待处理状态// 如果获取成功则返回flagIdle,如果已终止则返回flagDestroyingfunction AcquireThread: TSynBackgroundThreadProcessStep;procedure WaitForFinished(start: Int64; const onmainthreadidle: TNotifyEvent); // 等待完成/// 当fProcessParams<>nil且fEvent被通知时,由Execute方法调用procedure Process; virtual; abstract; // 抽象方法,需在子类中实现
public/// 初始化线程// - 如果aOnIdle未设置(即等于nil),它将简单地等待后台进程完成,直到RunAndWait()返回// - 您可以定义一些回调来嵌套线程执行,例如,分配给TRestServer.BeginCurrentThread/EndCurrentThreadconstructor Create(const aOnIdle: TOnIdleSynBackgroundThread;const aThreadName: RawUtf8; const OnBeforeExecute: TOnNotifyThread = nil;const OnAfterExecute: TOnNotifyThread = nil); reintroduce;/// 销毁线程destructor Destroy; override;/// 在后台线程中异步启动Process抽象方法// - 等待进程完成,同时调用OnIdle()回调// - 在后台线程中引发的任何异常都将在调用者线程中转换// - 如果self未设置,或者从当前正在处理的同一线程调用(以避免OnIdle()回调中的竞态条件),则返回false// - 当后台进程完成时返回true// - OpaqueParam将用于指定后台进程线程安全的内容// - 此方法是线程安全的,即它将等待另一个线程已经启动的任何进程:// 您可以从任何线程调用此方法,即使其主要用途是从主UI线程调用function RunAndWait(OpaqueParam: pointer): boolean;/// 设置一个回调事件,在远程阻塞过程期间循环执行,// 例如,在长时间请求期间刷新UI// - 您可以为此属性分配一个回调,例如调用Application.ProcessMessages,// 以在后台线程中执行远程请求,但让UI仍然具有响应性:// mORMotUILogin.pas中的TLoginForm.OnIdleProcess和OnIdleProcessForm方法将符合此属性的预期// - 如果OnIdle未设置(即等于nil),它将简单地等待后台进程完成,直到RunAndWait()返回property OnIdle: TOnIdleSynBackgroundThread   read fOnIdle write fOnIdle;/// 如果后台线程处于活动状态,并且在处理过程中调用了OnIdle事件,则为TRUE// - 例如,用于确保没有来自用户界面消息的重新进入property OnIdleBackgroundThreadActive: boolean read GetOnIdleBackgroundThreadActive;/// 在Execute中每次处理之前触发的可选回调事件property OnBeforeProcess: TOnNotifyThread   read fOnBeforeProcess write fOnBeforeProcess;/// 在Execute中每次处理之后触发的可选回调事件property OnAfterProcess: TOnNotifyThread    read fOnAfterProcess write fOnAfterProcess;
end;

TSynBackgroundThreadEvent,TSynBackgroundThreadMethod,TSynBackgroundThreadProcedure,TSynBackgroundThreadProcess

TSynBackgroundThreadEvent 定义

/// 由 TSynBackgroundThreadEvent 调用的后台进程方法
// - 当执行Process虚拟方法时,将提供RunAndWait()方法中指定的OpaqueParam参数
TOnProcessSynBackgroundThread = procedure(Sender: TSynBackgroundThreadEvent;ProcessOpaqueParam: pointer) of object;/// 允许后台线程处理方法回调
TSynBackgroundThreadEvent = class(TSynBackgroundThreadMethodAbstract)
protectedfOnProcess: TOnProcessSynBackgroundThread; // 回调事件/// 仅调用OnProcess处理程序procedure Process; override; // 重写Process方法
public/// 初始化线程// - 如果aOnIdle未设置(即等于nil),它将简单地等待后台进程完成,直到RunAndWait()返回constructor Create(const aOnProcess: TOnProcessSynBackgroundThread;const aOnIdle: TOnIdleSynBackgroundThread;const aThreadName: RawUtf8); reintroduce; // 重引入构造函数/// 提供一个方法处理程序,在后台线程中执行// - 由RunAndWait()方法触发 - 该方法将等待直到完成// - 这里将提供RunAndWait()方法中指定的OpaqueParamproperty OnProcess: TOnProcessSynBackgroundThreadread fOnProcess write fOnProcess; // OnProcess属性,用于访问fOnProcess字段
end;

TSynBackgroundThreadMethod 定义

/// 允许后台线程处理可变的TThreadMethod回调
TSynBackgroundThreadMethod = class(TSynBackgroundThreadMethodAbstract)
protected/// 仅调用RunAndWait()方法中提供的TThreadMethodprocedure Process; override; // 重写Process方法
public/// 运行一次提供的TThreadMethod回调// - 使用此方法,而不是继承的RunAndWait()procedure RunAndWait(Method: TThreadMethod); reintroduce; // 重引入RunAndWait方法
end;

TSynBackgroundThreadProcedure 定义

/// 由 TSynBackgroundThreadProcedure 调用的后台进程过程
// - 当执行Process虚拟方法时,将提供RunAndWait()方法中指定的OpaqueParam参数
TOnProcessSynBackgroundThreadProc = procedure(ProcessOpaqueParam: pointer);/// 允许后台线程处理过程回调
TSynBackgroundThreadProcedure = class(TSynBackgroundThreadMethodAbstract)
protectedfOnProcess: TOnProcessSynBackgroundThreadProc; // 回调过程/// 仅调用OnProcess处理程序procedure Process; override; // 重写Process方法
public/// 初始化线程// - 如果aOnIdle未设置(即等于nil),它将简单地等待后台进程完成,直到RunAndWait()返回constructor Create(aOnProcess: TOnProcessSynBackgroundThreadProc;const aOnIdle: TOnIdleSynBackgroundThread;const aThreadName: RawUtf8); reintroduce; // 重引入构造函数/// 提供一个过程处理程序,在后台线程中执行// - 由RunAndWait()方法触发 - 该方法将等待直到完成// - 这里将提供RunAndWait()方法中指定的OpaqueParamproperty OnProcess: TOnProcessSynBackgroundThreadProc read fOnProcess write fOnProcess; // OnProcess属性,用于访问fOnProcess字段
end;

TSynBackgroundThreadProcess 定义

type// TSynBackgroundThreadProcess 类声明(稍后定义)TSynBackgroundThreadProcess = class;/// 由 TSynBackgroundThreadProcess 定期执行的事件回调TOnSynBackgroundThreadProcess = procedure(Sender: TSynBackgroundThreadProcess) of object;/// 能够以给定周期运行方法的 TThread 类TSynBackgroundThreadProcess = class(TSynBackgroundThreadAbstract)protectedfOnProcess: TOnSynBackgroundThreadProcess; // 定期执行的方法回调fOnException: TNotifyEvent; // 当 OnProcess 引发异常时执行的事件回调fOnProcessMS: cardinal; // 定期执行任务的时间间隔(毫秒)fStats: TSynMonitor; // 处理统计信息procedure ExecuteLoop; override; // 重写执行循环public/// 初始化线程以进行周期性任务处理// - 当 ProcessEvent.SetEvent 被调用或自上次处理以来过去了 aOnProcessMS 毫秒时,将调用 aOnProcess// - 如果 aOnProcessMS 为 0,则等待直到 ProcessEvent.SetEvent 被调用// - 您可以定义一些回调来嵌套线程执行,例如,分配给 TRestServer.BeginCurrentThread/EndCurrentThreadconstructor Create(const aThreadName: RawUtf8;const aOnProcess: TOnSynBackgroundThreadProcess;aOnProcessMS: cardinal; const aOnBeforeExecute: TOnNotifyThread = nil;const aOnAfterExecute: TOnNotifyThread = nil;aStats: TSynMonitorClass = nil;CreateSuspended: boolean = false); reintroduce; virtual;/// 终结线程并等待其结束destructor Destroy; override;/// 访问周期性任务的实现事件property OnProcess: TOnSynBackgroundThreadProcessread fOnProcess;/// 当 OnProcess 引发异常时执行的事件回调// - 提供的 Sender 参数是引发的异常实例property OnException: TNotifyEventread fOnException write fOnException;published/// 访问周期性任务处理的延迟时间(毫秒)property OnProcessMS: cardinal  read fOnProcessMS write fOnProcessMS;/// 处理统计信息// - 如果在类构造函数中 aStats 为 nil,则可能为 nilproperty Stats: TSynMonitor   read fStats;end;

TSynBackgroundThreadEvent 例程代码

usesSysUtils, Classes, // 引入必要的单元mormot.core.threads;typeTMyProcessEvent = procedure(Sender: TObject; Param: Pointer) of object;varMyProcessEvent: TMyProcessEvent;procedure MyBackgroundProcess(Sender: TObject; ProcessOpaqueParam: Pointer);
begin// 这里是后台处理的代码WriteLn('Background process running with param: ', Pointer(ProcessOpaqueParam)^);// 假设我们传递了一个Integer指针作为OpaqueParamInteger(ProcessOpaqueParam)^ := Integer(ProcessOpaqueParam)^ + 1;
end;procedure InitializeAndRunBackgroundThreadEvent;
varBGThread: TSynBackgroundThreadEvent;Param: PInteger;
beginNew(Param);Param^ := 10; // 初始化参数MyProcessEvent := MyBackgroundProcess;// 创建并启动后台线程事件BGThread := TSynBackgroundThreadEvent.Create(MyProcessEvent, // 传递我们的处理过程nil, // OnIdle回调,这里不使用'MyBackgroundThreadEventDemo');try// 运行后台线程并等待完成BGThread.RunAndWait(Param);WriteLn('Background process finished. New param value: ', Param^);finallyBGThread.Free; // 销毁线程对象Dispose(Param); // 释放参数内存end;
end;// 在程序的某个地方调用InitializeAndRunBackgroundThreadEvent

TSynBackgroundThreadMethod 例程代码

usesSysUtils, Classes,mormot.core.threads;procedure MyThreadMethod(Thread: TThread);
begin// 这里是线程方法的代码WriteLn('Thread method running in background');// 模拟一些耗时操作Sleep(1000);
end;procedure RunBackgroundThreadMethod;
varBGThread: TSynBackgroundThreadMethod;
begin// 创建后台线程方法对象BGThread := TSynBackgroundThreadMethod.Create(nil, nil, 'MyBackgroundThreadMethodDemo');try// 注意:这里我们重写了RunAndWait方法,所以直接传递TThreadMethodBGThread.RunAndWait(MyThreadMethod);finallyBGThread.Free; // 销毁线程对象end;
end;// 在程序的某个地方调用RunBackgroundThreadMethod

注意:上面的 TSynBackgroundThreadMethod示例中,我假设了 RunAndWait方法被重写以接受 TThreadMethod作为参数,但根据原始定义,这并不是直接支持的。通常,您会在 Process方法内部调用传入的 TThreadMethod。为了保持示例简单,我展示了如何可能使用它,但在实际应用中,您可能需要在 Process方法内部处理这一点。

TSynBackgroundThreadProcedure 例程代码

usesSysUtils, Classes,mormot.core.threads;procedure MyBackgroundProcedure(ProcessOpaqueParam: Pointer);
begin// 这里是后台过程的代码WriteLn('Background procedure running with param: ', Pointer(ProcessOpaqueParam)^);// 假设我们传递了一个字符串指针作为OpaqueParamWriteLn('String param: ', PString(ProcessOpaqueParam)^);
end;procedure InitializeAndRunBackgroundThreadProcedure;
varBGThread: TSynBackgroundThreadProcedure;Param: PString;
beginNew(Param);Param^ := 'Hello, Background!';// 创建并启动后台线程过程BGThread := TSynBackgroundThreadProcedure.Create(MyBackgroundProcedure, // 传递我们的处理过程nil, // OnIdle回调,这里不使用'MyBackgroundThreadProcedureDemo');try// 运行后台线程并等待完成BGThread.RunAndWait(Param);finallyBGThread.Free; // 销毁线程对象Dispose(Param); // 释放参数内存end;
end;// 在程序的某个地方调用InitializeAndRunBackgroundThreadProcedure

TSynBackgroundThreadProcess 例程代码

usesSysUtils, Classes, // 引入SysUtils和Classes单元以使用WriteLn和TThread等mormot.core.threads;procedure MyProcessMethod(Sender: TSynBackgroundThreadProcess);
beginWriteLn('Process method called in background thread.');// 在这里执行您的后台处理逻辑
end;varBGThread: TSynBackgroundThreadProcess;begintry// 创建TSynBackgroundThreadProcess实例BGThread := TSynBackgroundThreadProcess.Create('MyBackgroundThread', // 线程名称MyProcessMethod, // 周期性执行的方法1000, // 周期时间,单位为毫秒nil, // OnBeforeExecute回调,这里不使用nil  // OnAfterExecute回调,这里不使用// aStats和其他参数根据需要进行设置);try// 启动线程(注意:在TSynBackgroundThreadProcess的构造函数中,// 如果CreateSuspended参数为false,则线程将自动启动)// 在这个例子中,我们假设CreateSuspended默认为false// 等待一段时间以观察后台线程的行为// 注意:在实际应用中,您可能不需要这样做,因为主线程可能会继续执行其他任务Sleep(5000); // 等待5秒finally// 销毁线程对象(注意:在析构函数中,线程将尝试优雅地终止)BGThread.Free;// 等待线程真正结束(可选,但在这个例子中我们依赖析构函数的行为)end;excepton E: Exception doWriteLn('Error: ' + E.Message);end;WriteLn('Program ended.');
end.

注意:在上面的示例中,我假设TSynBackgroundThreadProcess的构造函数有一个CreateSuspended参数(这在标准的TThread构造函数中是存在的),但根据您提供的类定义,这个参数实际上并没有在TSynBackgroundThreadProcess的构造函数中明确列出。如果TSynBackgroundThreadProcess是自动启动线程的,那么您可能不需要显式调用任何启动方法。

TSynBackgroundTimer 例程代码

usesSysUtils, // 引入SysUtils单元以使用WriteLnmormot.core.threads;procedure MyTimerProcess(Sender: TSynBackgroundTimer; const Msg: RawUtf8);
beginWriteLn('Timer process called in background thread. Message: ' + Msg);// 在这里执行您的定时任务逻辑
end;varTimer: TSynBackgroundTimer;begintry// 创建TSynBackgroundTimer实例Timer := TSynBackgroundTimer.Create('MyBackgroundTimer' // 线程名称// 其他参数根据需要进行设置,这里省略了OnBeforeExecute、OnAfterExecute、aStats和aLogClass);try// 启用一个周期性任务,每2秒执行一次Timer.Enable(@MyTimerProcess, 2);// 向任务队列添加消息,并请求立即执行(尽管在这个上下文中,立即执行可能不会立即发生)Timer.EnQueue(@MyTimerProcess, 'Hello from background timer!', true);// 等待一段时间以观察后台定时器的行为// 注意:在实际应用中,您可能不需要这样做,因为主线程可能会继续执行其他任务Sleep(10000); // 等待10秒// 禁用周期性任务(在这个示例中我们不会禁用它,但展示了如何禁用)// Timer.Disable(@MyTimerProcess);finally// 销毁TSynBackgroundTimer实例(注意:在实际应用中,您可能希望等待所有后台任务完成后再销毁定时器)// 但在这个简单示例中,我们立即销毁它Timer.Free;// 由于我们立即销毁了定时器,并且主线程继续执行(尽管在这个示例中被Sleep阻塞了),// 因此后台线程可能没有机会执行更多的回调。// 在实际应用中,您应该确保在销毁定时器之前给后台线程足够的时间来完成其工作。end;excepton E: Exception doWriteLn('Error: ' + E.Message);end;WriteLn('Program ended.');
end.

在上面的TSynBackgroundTimer示例中,我展示了如何创建定时器、启用周期性任务、向任务队列添加消息,并等待一段时间以观察定时器的行为。请注意,由于我们调用了Sleep并且立即销毁了定时器,因此后台线程可能没有机会执行更多的回调。在实际应用中,您应该确保在销毁定时器之前给后台线程足够的时间来完成其工作,或者调用Timer.WaitUntilNotProcessing(如果该类提供了这样的方法)来等待所有后台任务完成。然而,根据提供的类定义,TSynBackgroundTimer并没有直接提供WaitUntilNotProcessing方法,所以您可能需要实现自己的同步机制来达到这个目的。

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

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

相关文章

私有云盘-可道云-安装和使用和数据迁移

私有云盘是什么 随着云计算和移动办公大潮的到来,iPad、智能手机等家庭联网设备不断增多,以及搭载小容量SSD笔记本电脑的流行,能够跨平台分享的个人云服务需求不断增长;而今天的个人云服务也已经极大丰富,从2TB的百度网盘到商务人士中流行的Dropbox和Box个人云,不但免费,…

比赛获奖的武林秘籍:04 电子类比赛嵌入式开发快速必看的上手指南

本文主要介绍了电子类比赛中负责嵌入式开发同学的上手比赛的步骤、开发项目的流程和具体需要学习的内容,并结合自身比赛经历给出了相关建议。比赛获奖的武林秘籍:04 电子类比赛嵌入式开发快速必看的上手指南 摘要 本文主要介绍了电子类比赛中负责嵌入式开发同学的上手比赛的步…

线程饥饿问题——b2b - Thread starvation or clock leap detected (housekeeper delta=5h28m19s393ms972......

原因:在方法上配置了 @Async 注解进行异步执行,但是没有在主配置类上配置 @EnableAsync 启动异步执行。 修改前 修改后

SpringBoot项目启动,运行停留在标题处

详情: 原因:yml文件存在问题,比如:在切换生产环境和开发环境的配置文件时,yml名称写错,如下,图,此处多写了一个p。解决办法:修改为正确的配置文件,即可。

git合并代码方法

你合并代码用 merge 还是用 rebase ? macrozheng 2024年07月08日 14:10 江苏 1人听过以下文章来源于古时的风筝 ,作者风筝古时的风筝. 写代码是一种爱好,写文章是一种情怀。mall学习教程官网:macrozheng.com 你们平时合并代码的时候用 merge 还是 rebase? 我问了一圈,发现…

秒杀圣经(2):10Wqps秒杀,16大架构绝招,一文帮你秒变架构师

文章很长,且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录 博客园版 为您奉上珍贵的学习资源 : 免费赠送 :《尼恩Java面试宝典》 持续更新+ 史上最全 + 面试必备 2000页+ 面试必备 + 大厂必备 +涨薪必备 免费赠送 :《尼恩技术圣经+高并发系列PDF》 ,帮你 实现技术自由,…

写入多维表格失败

原因一: 没有获取到正确的table_id 解决办法将多维表格在浏览器打开,url的这部分就是table_id,如下图。由于模板中的设置多维表格模块需要输入网址,所以建议将网址和table_id一起复制

【算法篇】KMP算法,一种高效的字符串匹配算法

我们今天了解一个字符串匹配算法-KMP算法,内容难度相对来说较高,建议先收藏再细品!!! KMP算法我们今天了解一个字符串匹配算法-KMP算法,内容难度相对来说较高,建议先收藏再细品!!!KMP算法的基本概念 KMP算法是一种高效的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.…

飞书集成平台,流程触发器触发,没有运行日志

原因:飞书平台自动关联自建应用时,回调地址生成存在问题。解决办法:将飞书的触发器回调地址的内容,复制到关联的自建应用的事件回调地址中

NOIP2024模拟1

NOIP2024模拟1\(T1\) GHzoj 3752. 分糖果 \(100pts\)设最终答案中有 \(a\) 个小组中的小朋友的糖数 \(\mod 3\) 均等于 \(1\) , \(b\) 个小组中的小朋友的糖数 \(\mod 3\) 互不相等, \(c\) 个小组中的小朋友的糖数 \(\mod 3\) 均等于 \(0\) , \(d\) 个小组中的小朋友的糖数 …

工具安装

虚拟机——VMware安装 Vmware官方地址kali镜像 kali镜像win10镜像(教育版) 工具站卸载工具——geek安装文件检索工具——everything everything下载地址截图工具——snipaste snipaste下载地址解压缩工具——7.zip 7.zip下载地址 文本编辑器——notepad++ notepad++下载地址 …

分拆、杨图和杨表

分拆、杨图和杨表\(1.\) 定义和性质\(\textbf{定义 1 } \text{(分拆)}\) 定义整数 \(n\) 的一个拆分为 \(\lambda = (\lambda_1, \lambda_2, \dots, \lambda_m)\),满足 \(\forall i, \lambda_i \ge \lambda_{i + 1}\),且 \(\lambda_i\) 的加和为 \(n\)。记其为 \(\lambda \vd…

常见的概率分布

1.离散型分布 1.1 两点分布(伯努利分布/贝努利分布/0-1分布) 称随机变量 \(X\) 服从参数为 \(p\) 的伯努利分布,如果它分别以概率 \(p\) 和 \(1-p\) 取 1 和 0 为值。​ \[P(X=k)=p^k(1-p)^{1-k}, \quad k=0,1\\ X\sim B(1,p)\\ E(X)=p\\ D(X)=p(1-p) \]1.2 二项分布 n次独立…

python使用flask框架生成excle返回前端(包含图片、表格、表头灰色、表格加边框)

python使用flask框架生成excle文档,文档中包含图片和表格,其中表格要包含图片、表格、表头灰色、表格加边框,照片和表格不重叠。 逻辑:获得图片的高度,根据高度计算表格从第几行开始插入。 效果图:代码:import openpyxl from openpyxl.styles import PatternFill from o…

生成扩散模型漫谈(二):DDPM = 自回归式VAE

在文章《生成扩散模型漫谈(一):DDPM = 拆楼 + 建楼》中,我们为生成扩散模型DDPM构建了“拆楼-建楼”的通俗类比,并且借助该类比完整地推导了生成扩散模型DDPM的理论形式。在该文章中,我们还指出DDPM本质上已经不是传统的扩散模型了,它更多的是一个变分自编码器VAE,实际…

生成扩散模型漫谈(三):DDPM = 贝叶斯 + 去噪

到目前为止,笔者给出了生成扩散模型DDPM的两种推导,分别是《生成扩散模型漫谈(一):DDPM = 拆楼 + 建楼》中的通俗类比方案和《生成扩散模型漫谈(二):DDPM = 自回归式VAE》中的变分自编码器方案。两种方案可谓各有特点,前者更为直白易懂,但无法做更多的理论延伸和定量…

ComfyUI进阶篇:ComfyUI核心节点(四)

ComfyUI核心节点(四) 前言: 学习ComfyUI是一场持久战。当你掌握了ComfyUI的安装和运行之后,会发现大量五花八门的节点。面对各种各样的工作流和复杂的节点种类,可能会让人感到不知所措。在这篇文章中,我们将用通俗易懂的语言对ComfyUI的核心节点进行系统梳理,并详细解释…

全网最全EdgeMesh QA手册

https://zhuanlan.zhihu.com/p/585749690全网最全EdgeMesh Q&A手册Poorunga今天摸大鱼 24 人赞同了该文章​目录收起转载请注明出处前言定位模型问题一:Failed to watch xxx: failed to list xxx: no kind xxx ; Reflector ListAndWatch xxx (total time 10003ms)问题二:…

.NetCore中EFCore for MySql整理MySql.EntityFrameworkCore

一、MySql.EntityFrameworkCore 这个是官方给的一个EF操作MySql数据库的框架。 使用方法跟EF for SqlServer 一样。二、安装命令NuGet\Install-Package MySql.EntityFrameworkCore -Version 8.0.5 项目依赖 安装后的结果: 三、 EF Code First 模式连接数据库更多: C#程序调…

Caterpillar on a Tree

首先一个很显然的地方就是使用传送门肯定是在叶子节点使用,我们来考虑一下整个过程是怎么样的 为了方便,我们不妨假设可以传送回根节点\(k+1\)次,然后要求最后回到根节点 我们先从根节点走到某一个叶子结点,然后再从这个叶子节点走到另一个叶子节点,然后继续走到另一个叶子…