SMC状态机 讲解2 从模型到SMC

SMC状态机 讲解2 从模型到SMC

  • 1、实例化有限状态机(FSM)
  • 2、简单转换 Simple Transition
  • 3、外部环回转换 External Loopback Transition
  • 4、内部环回转换 Internal Loopback Transition
  • 5、转换动作
  • 6、转换Guard
  • 7、转换参数
  • 8、Entry 和 Exit动作
  • 9、Push 转换
  • 10、Pop转换
  • 11、默认转换

1、实例化有限状态机(FSM)

private final AppClassContext _fsm;

public AppClass()
{
    // 初始化应用程序类
    // 实例化有限状态机
    // 注意:传递给FSM是安全的
    // 构造函数,因为只有FSM的构造函数
    // 将其存储在数据成员中
    _fsm = new AppClassContext(this);
}

// 实例化后输入FSM启动状态
// 应用对象
public void startWorking()
{
    _fsm.enterStartState();
    return;
}

2、简单转换 Simple Transition

Simple Transition

// State
Idle
{
    // 转换到下一个状态的动作
    Run        Running        {}
}

状态和转换名称的命名规则必须为“[A- za -z_][A- za -z0-9_]*”形式。

3、外部环回转换 External Loopback Transition

在这里插入图片描述

// State
Idle
{
    // 转换到下一个状态的动作
    Timeout    Idle           {}
}

外部环回确实离开当前状态并返回到当前状态。这意味着执行状态的exitentry操作。这与内部环回转换相反。

4、内部环回转换 Internal Loopback Transition

在这里插入图片描述

// 状态
Idle
{
    // 转换到下一个状态的动作
    Timeout    nil            {}
}

使用“nil”作为下一个状态将导致转换保持在当前状态,而不是离开它。这意味着状态的退出和进入操作不会被执行。这与外部环回转换相反。

5、转换动作

在这里插入图片描述

// 状态
Idle
{
    //转换
    Run
        // 下一个状态
        Running
        // 动作
        {
            StopTimer("Idle");
            DoWork();
        }
}
  1. 转换的动作必须包含在“{}”中。
  2. 动作的形式为“[A-Za-z] [A-Za-z0-9_ -] *()”。参数列表(argument list)必须为空或由逗号分隔的字面值组成。例如:整数(正数或负数、十进制、八进制或十六进制)、浮点数、双引号括起来的字符串、常量和转换参数。
  3. 操作必须是%class类中的成员函数,并且可以被状态机访问。通常这意味着c++中的公共成员函数或Java中的包。

动作参数包括:
4. 整数(例如1234)。
5. 浮点数(如12.34)。
6. 字符串(例如:“中的”)。
7. 一个转换参数。
8. 常量、#define或全局变量。
9. 独立的子程序或方法调用(例如event.getType())。

6、转换Guard

在这里插入图片描述

// State
Idle
{
    // Trans
    Run
      // Guard condition
      [ctxt.isProcessorAvailable() == true &&
       ctxt.getConnection().isOpen() == true]
       
        // Next State
        Running
        // Actions
        {
            StopTimer("Idle");
            DoWork();
        }

    Run nil {RejectRequest();}
}

guard必须包含一个条件,该条件是有效的目标语言源代码——也就是说,它将是一个有效的“if”语句。定义的guard可能包含&&s、||s、比较运算符(==、<等)和嵌套表达式。SMC将您的保护条件逐字复制到生成的输出中。

如果guard条件的计算结果为true,则进行转换。如果gurad条件的计算结果为false,则发生以下情况之一(按优先级排序):

  1. 如果状态有另一个具有相同名称和参数的受保护转换,则检查该转换的保护。
  2. 否则,如果状态有另一个具有相同名称和参数列表的未保护转换,则进行该转换。
  3. 如果以上都不是,则遵循默认的转换逻辑。

一个状态可以有多个具有相同名称和参数列表的转换,只要它们都有唯一的gurad。当一个状态确实有多个具有相同名称的转换时,在排序它们时必须小心。状态机编译器将以与您使用的相同的从上到下的顺序检查转换,除了未保护的版本。只有当所有被保护的版本都失败时,才会采取这种做法。guard排序只有在guard不是互斥的情况下才重要,也就是说,对于同一个事件,多个gurad的值可能为true。

7、转换参数

在这里插入图片描述

// State
Idle
{
    // Transition
    Run(msg: const Message&)

      // Guard condition
      [ctxt.isProcessorAvailable() == true &&
       msg.isValid() == true]

        // Next State
        Running
        // Actions
        {
            StopTimer("Idle");
            DoWork(msg);
        }

    Run(msg: const Message&)
        // Next State    Actions
        nil              {RejectRequest(msg);}
}

Note:当使用转换guard和转换参数时,同一转换的多个实例必须具有相同的参数列表。就像c++和Java方法一样,Run(msg: const Message&)和Run()不是同一个转换。在使用多个gurad定义相同的转换时,如果不能使用相同的参数列表,将导致生成不正确的代码。

Tcl “arguments”:
虽然Tcl是一种无类型语言,但Tcl区分了按值调用和按引用调用。默认情况下,如果转换参数没有指定类型,SMC将生成按值调用的Tcl代码。但可以使用"value"或"reference"这些人为类型。

如果你的Tcl-targeted FSM有一个转换:

DoWork(task: value)
    Working
    {
        workOn(task);
    }

则生成的Tcl为:

public method DoWork {task} {
    workOn $this $task;
}

如果你的Tcl-targeted FSM有一个转换:

DoWork(task: reference)
    Working
    {
        workOn(task);
    }

则生成的Tcl为:

public method DoWork {task} {
    workOn $this task;
}

8、Entry 和 Exit动作

在这里插入图片描述

当转换离开某个状态时,它会在任何转换操作之前执行该状态的退出操作。当转换进入某个状态时,它执行该状态的进入操作。转换按以下顺序执行操作:

  1. “From”状态的退出动作。
  2. 将当前状态设置为空。
  3. 转换操作的顺序与.sm文件中定义的顺序相同。
  4. 将当前状态设置为“to”状态。
  5. “To”状态的进入动作。
// 状态
Idle //闲置
Entry {StartTimer("Idle", 1); CheckQueue();}//进入该状态时,执行该操作
Exit {StopTimer("Idle");} //离开该状态时,执行该操作
{
    //转换操作
}

从6.0.0版本开始,SMC生成一个enterStartState方法,该方法执行开始状态的进入动作。现在由应用程序在实例化有限状态机后调用start方法。如果不适合在启动时执行入口操作,则不要调用enterStartState。无需调用此方法来设置有限状态机的启动状态,这在FSM实例化时完成。此方法仅用于执行启动状态的进入操作。

如果要调用此方法,请确保在上下文类的构造函数之外调用。这是因为entry调用类方法。如果在上下文类的构造函数中调用enterStateState,则上下文实例将在完成初始化之前被引用,这是一件不好的事情。

enterStartState不防止被多次调用。它应该最多调用一次,并且在发出任何转换之前调用。不遵循这一要求可能会导致不适当的有限状态机行为。

是否执行状态的Entry和Exit操作取决于所采取的转换类型。下表显示了哪些转换执行“from”状态的Exit动作,哪些转换执行“to”状态的Entry动作。

转换类型执行“From”状态的Exit动作?执行“To状态的”Entry动作?
Simple Transition
External Loopback Transition
Internal Loopback Transition
Push 转换
Pop 转换

9、Push 转换

在这里插入图片描述

// SMC v1.3.2版本语法
Running
{
    Blocked    BlockPop/push(WaitMap::Blocked)  {GetResource();}
}

这将导致状态机:

  1. 转换到 BlockPop 状态。

  2. 执行 BlockPop entry 动作。

  3. PushWaitMap::Blocked 状态。

  4. 执行 WaitMap::Blocked entry 动作。

当WaitMap发出pop转换时,控制权将返回到BlockPop,并且从这里发出pop转换。

当一个状态有两个不同的转换,这两个转换推送到相同的状态,但需要以不同的方式处理弹出转换时,使用这个新语法。例如:

Idle
{
    NewTask     NewTask/push(DoTask)    {}
    RestartTask OldTask/push(DoTask)    {}
}

NewTask
{
    TaskDone    Idle                    {}
    // Try running the task one more time.
    TaskFailed  OldTask/push(DoTask)    {}
}

OldTask
{
    TaskDone    Idle                    {}
    TaskFailed  Idle                    {logFailure();}
}

10、Pop转换

在这里插入图片描述

pop转换与push转换的不同之处在于:

  1. 未指定最终状态。这是因为pop转换将返回到发出相应推送的任何状态。
  2. pop转换有一个可选参数:转换名称 transition name。

在上面的例子中,如果资源请求被授予,则状态机返回到执行推送的相应状态,然后进行该状态的OK转换。如果请求被拒绝,除了采取FAILED转换外,还会发生相同的事情。对应的push转换代码为:

Running
{
    Blocked    push(WaitMap::Blocked)    {GetResource();}
    
    // Handle the return "transitions" from WaitMap.
    OK   nil   {}
    FAILED     Idle   {Abend(INSUFFICIENT_RESOURCES);}
}

从SMC v. 1.2.0开始,可以在pop转换的transition参数之后添加其他参数。这些附加参数与传递给操作的其他参数一样,将被传递到命名转换中。按照上面的例子,给定pop转换pop(FAILED, errorCode, reason),那么FAILED应该被编码为:

FAILED(errorCode: ErrorCode, reason: string)
    Idle
    {
        Abend(errorCode, reason);
    }

11、默认转换

如果一个状态接收到一个在该状态中没有定义的转换,SMC会有两个独立的机制来处理这种情况。

  1. “Default”状态。每个%map都可以有一个名为“Default”的特殊状态(注意D为大写)。与所有其他状态一样,默认状态包含转换
Default
{
    //有效的运行请求,但转换在无效状态下发生。对有效消息发送拒绝回复。
    Run(msg: const Message&)
      [ctxt.isProcessorAvailable() == true &&
       msg.isValid() == true]
        nil
        {
            RejectRequest(msg);
        }

    // 在无效状态下接收到的无效消息将被忽略。
    Run(msg: const Message&)
        nil
        {}

    Shutdown
        ShuttingDown
        {
            StartShutdown();
        }
}

默认状态转换可能具有非默认转换的保护和参数特性。这意味着对于同一转换,默认状态可能包含多个受保护和一个不受保护的定义。

  1. “默认”转换。它被放置在状态中,用于备份所有转换。
Connecting
{
    // 现在连接到远端,可以登录了。
    Connected
        Connected
        {
            logon();
        }

    // 此时的任何其他转换都是错误的。
    // 请停止连接进程,稍后重试。
    Default
        RetryConnection
        {
            stopConnecting();
        }
}

因为任何转换都可以通过默认转换,所以默认转换:

  1. 可能没有参数列表。

  2. 默认转换可能需要一个guard。

  3. 将Default转换置于Default状态意味着将处理所有转换。

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

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

相关文章

chatGPT界面

效果图&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html> <head><title>复选框样式示例</title> </head> <style>* {padding:0;margin: 0;}.chatpdf{display: flex;height: 100vh;flex-direction: row;}.chatpdf .pannel{widt…

jenkins Linux如何修改jenkins 默认的工作空间workspace

由于jenkins默认存放数据的目录是/var/lib/jenkins&#xff0c;一般这个var目录的磁盘空间很小的&#xff0c;就几十G,所以需要修改jenkins的默认工作空间workspace 看到最后 环境 jenkins使用yum安装的 centos 7 正题 1 查看jenkins安装路径 [rootlocalhost jenkins_old_d…

Git 安装、配置并把项目托管到码云 Gitee

错误聚集篇&#xff1a; 由于我 git 碰见大量错误&#xff0c;所以集合了一下&#xff1a; git 把项目托管到 码云出现的错误集合_打不着的大喇叭的博客-CSDN博客https://blog.csdn.net/weixin_49931650/article/details/132460492 1、安装 git 1.1 安装步骤 1.1.1 下载对应…

网络渗透day2-Windows服务器服务管理相关

1.在Windows Server中&#xff0c;用于监视网络连接和流量的工具是&#xff1f; A.Event Viewer B.Performance Monitor C.Task Scheduler D.Resource Monitor 正确答案&#xff1a;D 你的答案&#xff1a;B 解析&#xff1a; 答案解析&#xff1a;Resource Monitor用于监…

2分钟搭建自己的GPT网站

如果觉得官方免费的gpt&#xff08;3.5&#xff09;体验比较差&#xff0c;总是断开&#xff0c;或者不会fanqiang&#xff0c;那你可以自己搭建一个。但前提是你得有gpt apikey。年初注册的还有18美金的额度&#xff0c;4.1号后注册的就没有额度了。不过也可以自己充值。 有了…

数据生成 | MATLAB实现MCMC马尔科夫蒙特卡洛模拟的数据生成

数据生成 | MATLAB实现MCMC马尔科夫蒙特卡洛模拟的数据生成 目录 数据生成 | MATLAB实现MCMC马尔科夫蒙特卡洛模拟的数据生成生成效果基本描述模型描述程序设计参考资料 生成效果 基本描述 1.MATLAB实现MCMC马尔科夫蒙特卡洛模拟的数据生成&#xff1b; 2.马尔科夫链蒙特卡洛方…

使用Vscode调试shell脚本

在vcode中安装bash dug插件 在vcode中添加launch.json配置&#xff0c;默认就好 参考&#xff1a;http://www.rply.cn/news/73966.html 推荐插件&#xff1a; shellman(支持shell,智能提示) shellcheck(shell语法检查) shell-format(shell格式化)

35、下载、安装 jdk11 记录,Idea中把项目从 jdk8 换 jdk 11

之前一直用jdk8&#xff0c;现在改成 11的试试看 登录官网下载这个11 https://www.oracle.com/cn/java/technologies/downloads/#java11-windows 下载jdk的oracle官网 需要自己注册oracle账户 修改环境变量的 JAVA_HOME Path 路径这里原本添加8的时候有了&#xff0c;不…

axios 进阶

axios 进阶 接口传参方式 使用 xhr 原生技术或者是 axios 时&#xff0c;它的 post 传参方式是键值对的形式 keyvalue。但是在实际开发中一般是使用对象的形式定义数据&#xff0c;方便读取和赋值。所以当我们需要发起请求时可以通过 qs 这一款插件将对象转成键值对形式&…

Socket通信与WebSocket协议

文章目录 目录 文章目录 前言 一、Socket通信 1.1 BIO 1.2 NIO 1.3 AIO 二、WebSocket协议 总结 前言 一、Socket通信 Socket是一种用于网络通信的编程接口&#xff08;API&#xff09;&#xff0c;它提供了一种机制&#xff0c;使不同主机之间可以通过网络进行数据传输和通信…

【校招VIP】CSS校招考点之水平/垂直居中

考点介绍&#xff1a; 前端布局非常重要的一环就是页面框架的搭建&#xff0c;也是最基础的一环。在页面框架搭建之中&#xff0c;又有居中布局/多列布局/全局布局。今天介绍一下居中布局的水平居中和垂直居中。 『CSS校招考点之水平/垂直居中』相关题目及解析内容可点击文章末…

学习左耳听风栏目90天——第八天 8/90(学习左耳朵耗子的工匠精神,对技术的热爱)【答疑解惑:渴望、热情和选择】

答疑解惑&#xff1a;渴望、热情和选择 如何抽出时间学习&#xff1f;1. 要热爱学习&#xff0c;渴望学习&#xff0c;从学习中获取快乐 如何抽出时间学习&#xff1f; 1. 要热爱学习&#xff0c;渴望学习&#xff0c;从学习中获取快乐

linux服务TCP参数配置

Linux TCP参数配置 阿里云规范 1.【推荐】高并发服务器建议调小 TCP 协议的 time_wait 超时时间。 说明&#xff1a;操作系统默认 240 秒后&#xff0c;才会关闭处于 time_wait 状态的连接&#xff0c;在高并发访问下&#xff0c;服务器端会因为处于 time_wait 的连接数太多&am…

消息队列——RabbitMQ(一)

MQ的相关概念 什么事mq MQ(message queue)&#xff0c;从字面意思上看&#xff0c;本质是个队列&#xff0c;FIFO 先入先出&#xff0c;只不过队列中存放的内容是 message 而已&#xff0c;还是一种跨进程的通信机制&#xff0c;用于上下游传递消息。在互联网架构中&#xff…

创建web应用程序,React和Vue怎么选?

React和Vue都是创建web应用程序的绝佳选择。React得到了科技巨头和庞大的开源社区的支持&#xff0c;代码库可以很大程度地扩展&#xff0c;允许你创建企业级web应用程序。React拥有大量合格甚至优秀的开发人员粉丝&#xff0c;可以解决你在开发阶段可能遇到的任何问题。 毫无疑…

OpenEuler华为欧拉系统安装

OpenEuler华为欧拉系统安装 一、OpenEuler简介1、OpenEuler概述2、OpenEuler特性 二、OpenEuler部署安装1、安装前配置2、安装引导3、选择语言4、安装信息摘要 三、欧拉系统安装图形化界面1、需要在超级管理员&#xff0c;在root权限下操作2、启动图形化界面 四、手动安装VMwar…

Go framework-Kratos

一、Go framework 框架Github开源时间开源方Kratoshttps://github.com/go-kratos/kratos2019Bilibiligo-kithttps://github.com/go-kit/kit/2015团队开源go-zerohttps://github.com/tal-tech/go-zero2020团队开源TarsGohttps://github.com/TarsCloud/TarsGo2018腾讯Jupiterhtt…

计算机竞赛 基于人工智能的图像分类算法研究与实现 - 深度学习卷积神经网络图像分类

文章目录 0 简介1 常用的分类网络介绍1.1 CNN1.2 VGG1.3 GoogleNet 2 图像分类部分代码实现2.1 环境依赖2.2 需要导入的包2.3 参数设置(路径&#xff0c;图像尺寸&#xff0c;数据集分割比例)2.4 从preprocessedFolder读取图片并返回numpy格式(便于在神经网络中训练)2.5 数据预…

Linux 定时任务 crontab 用法学习整理

一、linux版本 lsb_release -a 二、crontab 用法学习 2.1&#xff0c;crontab 简介 linux中crontab命令用于设置周期性被执行的指令&#xff0c;该命令从标准输入设备读取指令&#xff0c;并将其存放于“crontab”文件中&#xff0c;以供之后读取和执行。cron 系统调度进程。…

简述docker的网络模式

Docker 提供了多种网络模式&#xff0c;用于控制容器之间以及容器与主机之间的网络通信。以下是 Docker 的一些常见网络模式 briage模式&#xff1a; docker容器启动时默认就是该模式,在该模式下&#xff0c;docker容器会连接到一个名为docker0的虚拟以太网桥上&#xff0c;通…