SMC状态机 讲解1 XX.sm文件详解

news2024/12/24 10:45:27

SMC状态机 讲解1.4 XX.sm文件

  • 1、Task类
  • 2、FSM任务
  • 3、创建SMC.sm文件
  • 4、定义FSM状态
  • 5、定义转换 transition
  • 6、定义FSM转换动作
  • 7、定义FSM默认转换
  • 8、定义状态Entry/Exit 动作
  • 9、连接Task与Task FSM

1、Task类

SMC为对象(不是进程或应用程序,而是单个对象)生成有限状态机。如果有接收异步回调的对象,并且对象响应这些回调是基于对象状态的,那么SMC提供了一个强大的解决方案。

package com.acme.supercron;

public final class Task implements TaskEventListener,
               TimerEventListener
{
    public Task()
    {
        // 对象初始化
        ...
    }

    //-----------------------------------------------------------
    // TaskEventListener Interface Implemenation.
    //

    // 未完成任务在指定时间片内继续工作的时间。
    public void start(long timeSlice)
    {
        ...
    }

    // 当一个正在运行的、未完成的任务应该暂停运行时调用,即使它的时间片没有过期。
    // 注意:当时间片过期时,任务的运行也会暂停。
    public void suspend()
    {
        ...
    }

    // 当未完成的任务被阻塞时调用。被阻塞的任务在解除阻塞后能够继续运行。
    public void block()
    {
        ...
    }

    // 当阻塞的任务被解除阻塞并允许继续运行时调用。
    public void unblock()
    {
        ...
    }

    // 当一个未完成的任务被永久停止时调用。
    // 然后删除已停止的任务。
    public void stop()
    {
        ...
    }

    // 当任务被删除时调用。出现以下情况之一调用:
    //1.任务已经完成运行并且现在被停止
    //2.系统正在关闭并且所有任务都将立即终止时,任务将被删除。
    public void delete()
    {
        ...
    }

    //
    // end of TaskEventListener Interface Implemenation.
    //-----------------------------------------------------------

    //-----------------------------------------------------------
    // TimerEventListener Interface Implementation.
    //

    // 当时间片计时器到期时调用。如果运行,任务挂起。
    public void handleTimeout(TimerEvent event)
    {
        ...
    }

    //
    // end of TimerEventListener Interface Implementation.
    //-----------------------------------------------------------

    // Remainder of class definition.
    ...
}

2、FSM任务

任务FSM示意图如下:
在这里插入图片描述任务的状态是:

  1. Running:任务正在运行。允许任务在指定的时间限制内运行。
  2. Suspended:任务尚未完成,正在等待再次运行。
  3. Stopped:任务已完成运行或外部停止。
  4. Blocked:未完成的任务被外部阻止再次运行。它将保持这种状态,直到停止或解除阻塞。
  5. Stopping:任务在进入停止状态前,正在清理已分配的资源。
  6. Deleted:任务完全停止,关联资源全部返回。现在可以安全地删除任务了。FSM的结束状态。

3、创建SMC.sm文件

XX.sm 文件是一个没有定义状态或转换的框架。包含以下特性:

关键字作用
%package指定此FSM所属的类包,与关联的Task类包相同。
%fsmclass指定生成的有限状态机类名。如果未指定%fsmclass,则有限状态机类名默认为TaskContext。这个关键字不是必需的。
%fsmfile指定生成的有限状态机类文件名
%access指定生成的类的可访问级别(只在生成Java和c#代码时有效)
%start指定FSM的启动状态
%mapFSM的名称
%{ %}编写注释

代码实现:

%{
//编写注释
//...
%}
 
// This FSM works for the Task class only and only the Task
// class may instantiate it.
 
%class Task
%package com.acme.supercron
%fsmclass TaskFSM
%fsmfile TaskFSM
%access package
 
// A %map name cannot be the same as the FSM class name.
%start TaskMap::Suspended
%map TaskMap
%%
    ...
%%

4、定义FSM状态

在%map TaskFSM %% … %% 分隔符中定义FSM状态

// 此FSM只对Task类起作用
// class可以实例化.
%class Task
%package com.acme.supercron
%fsmclass TaskFSM
%fsmfile TaskFSM
%access package
 
// %map 名字不能与FSM类名相同
%start TaskMap::Suspended
%map TaskMap
%%
Suspended
{
    ...
}
Running
{
    ...
}
// 此处等待解锁、停止、删除
Blocked
{
    ...
}
 
Stopping
{
    ...
}
Stopped
{
    ...
}
Deleted
{
    ...
}
...
%%

5、定义转换 transition

转换由四个部分组成:

  1. transition name:转换名称
  2. transition guard:转换保护(可选)
  3. 转换结束时的状态
  4. transition action:转换动作

下面介绍Stop、Block和Delete转换:

// 该FSM只对Task类工作,并且只对Task类工作
// 类可以实例化
%class Task
%package com.acme.supercron
%package package
%fsmclass TaskFSM
%fsmfile TaskFSM
%access package
 
// %map名称不能与FSM的类名相同
%start TaskMap::Suspended
%map TaskMap
%%
Suspended
{
    // Time to do more work.
    // 时间片持续时间作为转换传入
    // argument.
    Start(timeslice: long) // 转换名称
        Running // 转换结束后的状态
        {
            ... // 执行动作
        }
}
 
Running
{
    // 等待时间片
    Suspend //转换名称
        Suspended //转换结束后的状态
        {
            ...
        }
 
    // Task已经完成.
    Done
        Stopped
        {
            ...
        }
}
 
// 等待解锁、停止或删除
Blocked
{
    // The task may continue working now.
    Unblock
        Suspended
        {
            ...
        }
}
Stopping
{
    // task结束
    Stopped
        Stopped
        {
            ...
        }
}
Stopped
{
    ...
}
Deleted
{
    ...
}
 
...
%%

6、定义FSM转换动作

转换操作是FSM和应用程序类Task之间的第一次耦合。actionsTask的方法。这些方法必须具有以下属性:

  1. FSM可访问,这意味着至少有public方法。或者如果在同一个package中,则有package方法。
  2. 有void返回类型。如果该方法确实返回值,则FSM将忽略该值。

SMC对转换参数没有语法限制,只是将它们用“()”括号括起来并以逗号分隔。

// This FSM works for the Task class only and only the Task
// class may instantiate it.
%class Task
%package com.acme.supercron
%fsmclass TaskFSM
%fsmfile TaskFSM
%access package

// A %map name cannot be the same as the FSM class name.
%start TaskMap::Suspended
%map TaskMap
%%
Suspended
{
    // Time to do more work.
    // The timeslice duration is passed in as a transition
    // argument.
    Start(timeslice: long)
        Running
        {
            continueTask();
            startSliceTimer(timeslice);
        }
}

Running
{
    // Wait for another time slice.
    Suspend
        Suspended
        {
            stopSliceTimer();
            suspendTask();
        }

    // Task has completed.
    Done
        Stopped
        {
            stopSliceTimer();
            releaseResources();
        }
}

// Wait here to be either unblocked, stopped or deleted.
Blocked
{
    // The task may continue working now.

    // No actions needed.
    Unblock
        Suspended
        {}
}

Stopping
{
    // The task is now stopped.
    Stopped
        Stopped
        {
            releaseResources();
        }
}

Stopped
{
    ...
}

Deleted
{
    ...
}
...
%%

Task中的转换动作方法为:

package com.acme.supercron;

public final class Task implements TaskEventListener, TimerEventListener
{
    public Task()
    {
        // 对象初始化
        ...
    }

    //-----------------------------------------------------------
    // TaskEventListener Interface Implemenation.
    //

<snip>

    //
    // end of TaskEventListener Interface Implemenation.
    //-----------------------------------------------------------

    //-----------------------------------------------------------
    // TimerEventListener Interface Implementation.
    //

<snip>

    //
    // end of TimerEventListener Interface Implementation.
    //-----------------------------------------------------------


    //-----------------------------------------------------------
    // State Machine Actions.
    //

    // Activate the underlying task and get it running again.
    /* package */ void continueTask()
    {
        ...
        return;
    }

    // Inactivate the underlying task.
    /* package */ void suspendTask()
    {
        ...
        return;
    }

    // Start the timeslice timer for the given milliseconds.
    /* package */ void startSliceTimer(long timeslice)
    {
        ...
        return;
    }

    // Stop the timeslice timer.
    /* package */ void stopSliceTimer()
    {
        ...
        return;
    }

    // Return system resources from whence they came.
    /* package */ void releaseResources()
    {
        ...
        return;
    }

    //
    // end of State Machine Actions.
    //-----------------------------------------------------------

    
// Remainder of class definition.
    ...
}

7、定义FSM默认转换

现在已经定义了转换“Stop”、“Block”和“Delete”。这些转换没有开始状态的原因是,无论当前状态如何,都要进行转换。

  1. Stop:如果task仍然是alive的(处于Suspended、Running或Blocked状态),那么它必须立即转换到stop状态。如果任务为not alive(在其他三种状态下),则忽略此转换,因为task不再alive。
  2. Block:如果task处于Suspended或running状态,那么它将转换到Bolcked状态。否则该请求将被忽略。
  3. Delete:如果task处于除Deleted之外的任何状态,那么它必须转换到Deleted状态。

SMC提供了两种定义默认转换的方法:Default状态和Default转换。sm更新了默认的Stop, Block和Delete转换定义:

// This FSM works for the Task class only and only the Task
// class may instantiate it.
%class Task
%package com.acme.supercron
%fsmclass TaskFSM
%fsmfile TaskFSM
%access package

// A %map name cannot be the same as the FSM class name.
%start TaskMap::Suspended
%map TaskMap
%%
Suspended
{
    // Time to do more work.
    // The timeslice duration is passed in as a transition
    // argument.
    Start(timeslice: long)
        Running
        {
            continueTask();
            startSliceTimer(timeslice);
        }

    Block
        Blocked
        {
            blockTask();
        }

Running
{
    // Wait for another time slice.
    Suspend
        Suspended
        {
            stopSliceTimer();
            suspendTask();
        }

    Block
        Blocked
        {
            stopSliceTimer();
            blockTask();
        }

    // Task has completed.
    Done
        Stopped
        {
            stopSliceTimer();
            releaseResources();
        }
}

// Wait here to be either unblocked, stopped or deleted.
Blocked
{
    // The task may continue working now.
    // No actions needed.
    Unblock
        Suspended
        {}
}

Stopping
{
    // The task is now stopped.
    Stopped
        Stopped
        {
            releaseResources();
        }

    // We are stopping.
    Stop
        nil
        {}
}

Stopped
{
    // We are stopping.
    Stop
        nil
        {}

    // Ignore all transitions until deleted.
    Default
        nil
        {}
}

Deleted
{
    // Define all known transitions as loopbacks.
    Start(timeslice: long)
        nil
        {}

    Suspend()
        nil
        {}

    Block()
        nil
        {}

    Unblock()
        nil
        {}

    Done()
        nil
        {}

    Stop()
        nil
        {}

    Stopped()
        nil
        {}

    Delete()
        nil
        {}
}

Default
{
    // Three states follow this transition, three states ignore.
    // So define the active definition.
    Stop
        Stopping
        {
            stopTask();
        }

    // Block is ignored by four of six states.
    // Force the other two states to define this.
    // Note the "nil" end state. This is a loopback transition
    Block
        nil
        {}

    // All but the Delete state follow this transition. Define it here.
    Delete
        Deleted
        {}

    // Ignore a transition by default.
    Default
        nil
        {}
}
%%

blockTask()和stopTask()方法被添加到Task类中:

package com.acme.supercron;

public final class Task implements TaskEventListener, TimerEventListener
{
    public Task()
    {
        // Object initialization.
        ...
    }

<snip>

    //-----------------------------------------------------------
    // State Machine Actions.
    //

<snip>

    // Block the underlying task from running.
    /* package */ void blockTask()
    {
        ...
        return;
    }

    // Permanently stop the underlying task.
    /* package */ void stopTask()
    {
        ...
        return;
    }

<snip>

    //
    // end of State Machine Actions.
    //-----------------------------------------------------------

    // Remainder of class definition.
    ...
}

8、定义状态Entry/Exit 动作

当不处于Running状态时,应该停止时间片定时器。实现这一点的方法是在Running中添加一个Exit块,并将stopSliceTimer()动作移动到那里。

由于正在定义状态的Exit动作,因此将startSliceTimer()动作放入Entry块中似乎是很自然的。但反对的理由有两点:

  1. 进入运行状态的转换只有一次。将startSliceTimer()从Suspended的Start过渡移动到Running的entry动作没有任何好处。
  2. startSliceTimer()接受Start转换的时间片参数。如果startSliceTimer()是一个入口操作,那么它不能访问转换参数。解决这个问题的唯一方法是将切片时间存储在Task类中,然后在entry动作(startSliceTimer(ctext . getslicetime()))中立即检索它。现在,将动作移动到entry块比什么都不做还要糟糕。
// This FSM works for the Task class only and only the Task
// class may instantiate it.
%class Task
%package com.acme.supercron
%fsmclass TaskFSM
%fsmfile TaskFSM
%access package

// A %map name cannot be the same as the FSM class name.
%start TaskMap::Suspended
%map TaskMap
%%

<snip>
Running
    Exit
    {
        stopSliceTimer();
    }
{
    // Wait for another time slice.
    Suspend
        Suspended
        {
            // stopSliceTimer(); moved.
            suspendTask();
        }

    Block
        Blocked
        {
            // stopSliceTimer(); moved.
            blockTask();
        }

    // Task has completed.
    Done
        Stopped
        {
            // stopSliceTimer(); moved.
            releaseResources();
        }
}
<snip>
}
%%

9、连接Task与Task FSM

将FSMs连接到它们的应用程序类非常简单:

  1. 在Task类中添加数据成员TaskFSM _fsm
  2. 在Task的构造函数中实例化TaskFSM。
  3. 如果start状态有必须在创建FSM时执行的entry动作,那么在Task的构造函数之外调用_fsm.enterStartState()
  4. 当你需要发出一个转换时,调用_fsm相应的转换方法:
_fsm.Start(timeSlice);
package com.acme.supercron;

public final class Task
    implements TaskEventListener,
               TimerEventListener
{
    public Task()
    {
        // Object initialization.

        ...

        // Instantiate the FSM here but perform the initial
        // state's entry actions outside of the constructor
        // to prevent referencing this object before its
        // initialization is complete.
        _fsm = new TaskFSM(this);
    }

    // Execute the start state's entry actions by calling this
    // method. This method should be called only once and prior to
    // issuing any transitions. Therefore this method should be
    // called before registering this Task instance as a task and
    // timer event listener.
    public void startFSM()
    {
        _fsm.enterStartState();

        TaskManager.addListener(this);
    }

    //-----------------------------------------------------------
    // TaskEventListener Interface Implemenation.
    //

    // Time for the incomplete task to continue its work for the
    // specified time slice.
    public void start(long timeSlice)
    {
        _fsm.Start(timeSlice);
    }

    // Called when a running, incomplete task should suspend
    // running even though its time slice is not expired.
    // Note: the task's running is also suspended when the time
    // slice expires.
    public void suspend()
    {
        _fsm.Suspend();
    }

    // Called when an incomplete task is blocked. Blocked tasks
    // are able to continue running when unblocked.
    public void block()
    {
        _fsm.Block();
    }

    // Called when a blocked task is unblocked and allowed
    // to continue running.
    public void unblock()
    {
        _fsm.Unblock();
    }

    // Called when an incomplete task is permanently stopped.
    // Stopped tasks are then deleted.
    public void stop()
    {
        _fsm.Stop();
    }

    // Called when the task is deleted. Tasks are deleted when
    // either 1) the task has completed running and is now
    // stopped or 2) when the system is shutting down and all
    // are to terminate immediately.
    public void delete()
    {
        _fsm.Delete();
    }

    //
    // end of TaskEventListener Interface Implemenation.
    //-----------------------------------------------------------

    //-----------------------------------------------------------
    // TimerEventListener Interface Implementation.
    //

    // Called with the time slice timer has expired. If running,
    // the task is suspended.
    public void handleTimeout(TimerEvent event)
    {
        _fsm.Suspend();
    }

    //
    // end of TimerEventListener Interface Implementation.
    //-----------------------------------------------------------

<snip>

    // The associated finite state machine.
    private final TaskFSM _fsm;
}

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

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

相关文章

IT运维:使用数据分析平台监控DELL服务器

概述 在企业日常运维中&#xff0c;我们有着大量的服务器设备&#xff0c;设备故障一般可以通过常用的监控软件实现自动告警&#xff0c;但如果在管理运维中我们要做的不仅仅是发现故障&#xff0c;处理硬件故障&#xff0c;我们还需要进一步的了解&#xff0c;今年一共出现了多…

【Linux应用部署篇】在CSDN云IDE平台部署Etherpad文档编辑器

【Linux应用部署篇】在CSDN云IDE平台部署Etherpad文档编辑器 一、CSDN云IDE平台介绍1.1 CSDN云IDE平台简介1.2 CSDN云IDE平台特点 二、本次实践介绍2.1 本次实践介绍2.2 Etherpad简介 三、登录CSDN云IDE平台3.1 登录CSDN开发云3.2 登录云IDE3.3 新建工作空间3.4 进入工作空间 四…

【测试流程】敏捷软件测试流程分享

一、背景 分享一套高效可靠的软件测试流程&#xff0c;目的是更好的保障产品质量&#xff0c;更高效的完成测试任务&#xff0c;提供给需要的朋友。 二、软件测试流程

Web端报错

Chunk-vendors.2a8c602b.js&#xff1a;48混合内容&#xff1a;位于‘https://3323.sfdy13168.com/#/goodsManage’的页面通过HTTPS加载&#xff0c;但请求了不安全的XMLHttpRequest端点‘http://110.42.2.202:8087/file/upload’.。此请求已被阻止&#xff1b;内容必须通过HTT…

STM32CubeIDE(Timer)

目录 一、基本定时器 1、TIM6和TIM7简介 2、TIM6和TIM7主要特性 3、CubeMX配置 4、代码编写 二、通用定时器 1、简介 2、主要功能 3、生成PWM波 3.1 固定占空比 3.2 可变占空比 4、输出比较 5、输入PWM 5.1 CubeMX配置 5.2 代码编写 一、基本定时器 1、TIM6和TI…

IO多路转接(复用)多线程 select 并发

1.select // sizeof(fd_set) 128 1024 #include <sys/time.h> #include <sys/types.h> #include <unistd.h> #include <sys/select.h> int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);- 参数…

PyQt open3d 加载 显示点云

PyQt加载 显示点云&#xff0c;已经有三种方式&#xff0c;使用 open3d; 使用 vtk; 使用 pcl; 下面是使用 open3d: import sys import open3d as o3d import numpy as np import pyqtgraph.opengl as gl from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget, QFi…

yolov5的xml文件转txt文件格式(详细解释与完整代码供应)

文章目录 前言一、yolov5训练数据格式介绍1、txt的类别对应说明2、txt的文件说明3、txt文件格式3、yolov5训练文件形式 二、xml文件读取代码解读三、xml文件转txt文件1、xml转txt代码解读2、保存txt文件代码解读 四、完整代码 前言 本文章实现xml数据格式转yolov5的txt格式&am…

7、Idea下载安装与激活

1、下载 1.1 官网地址 官网地址 https://www.jetbrains.com/idea/ 点击访问 1.2 官网首页 1.3 点击右上角dowload进入以下页面选择版本 1.4 选择需要的版本进行下载 2、安装

日志系统——全局接口/宏函数优化

日志器模块完成后&#xff0c;我们的日志系统差不多就算完成了&#xff0c;但是在用户使用方面仍然需要优化 如上所示&#xff0c;当我们需要从日志器管理器中获取日志器时需要用上面一长串的方式获取&#xff0c;而我们写入日志时还需要让用户用宏表示文件和行号&#xff0c;这…

数据资产入表正式落地!企业如何进行数据资产管理

数字化时代&#xff0c;数据已经成为了个人、机构、企业乃至国家的重要战略资产。近日&#xff0c;财政部正式对外发布《企业数据资源相关会计处理暂行规定》&#xff0c;并自2024年1月1日开始施行。数据资产入表政策落地节奏超预期&#xff0c;标志着国家把数据作为生产要素的…

分发饼干【贪心算法】

分发饼干 假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。 对每个孩子 i&#xff0c;都有一个胃口值 g[i]&#xff0c;这是能让孩子们满足胃口的饼干的最小尺寸&#xff1b;并且每块饼干 j&#xff0c;都有一个…

Linux下的Shell基础——Shell概述和入门(一)

前言&#xff1a; Shell还是一个功能相当强大的编程语言&#xff0c;易编写、易调试、灵活性强。为了方便后续的学习&#xff0c;我们需要学习在Linux系统下的Shell编程 目录 一、Shell概述 1.Linux 提供的 Shell 解析器有 2. 默认的解析器是 bash 二、Shell 脚本入门 1.脚…

转置卷积的应用

目录 矩阵转置 一、转置卷积的背景 二、转置卷积的应用 三、转置卷积的区别 卷积 矩阵转置 矩阵的转置在信息处理中起到了重要的作用。在计算机科学领域&#xff0c;矩阵常用于表示图像、音频和视频等多媒体数据。当我们需要对这些数据进行处理时&#xff0c;常常需要进行…

前置微小信号放大器的作用是什么

前置微小信号放大器是一种电子设备&#xff0c;用于将弱信号放大到足够的水平以供后续处理。它在许多领域都有广泛的应用&#xff0c;如通信系统、无线电接收机、传感器接口等。 前置微小信号放大器的主要作用是增加信号的强度。当我们处理微弱信号时&#xff0c;如果不进行放大…

FMEA介绍以及在制造业中的应用

在现代制造业中&#xff0c;确保产品质量和流程稳定性是至关重要的任务。为了应对潜在的故障和风险&#xff0c;企业采用了多种方法和工具&#xff0c;其中之一便是故障模式和影响分析&#xff08;FMEA&#xff09;。FMEA是一种系统性、结构化的方法&#xff0c;用于识别潜在的…

【word密码】如何取消word限制?忘记密码?

Word文档设置了限制编辑&#xff0c;打开文件之后发现功能栏中都是灰色的&#xff0c;无法编辑文件&#xff0c;这种情况&#xff0c;我们点击审阅 – 限制编辑 然后在右侧会有弹框出现&#xff0c;我们点击底下的【停止保护】&#xff0c;输入word密码就可以取消限制编辑了 如…

2023高教社杯数学建模思路 - 复盘:人力资源安排的最优化模型

文章目录 0 赛题思路1 描述2 问题概括3 建模过程3.1 边界说明3.2 符号约定3.3 分析3.4 模型建立3.5 模型求解 4 模型评价与推广5 实现代码 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 描述 …

app宿主环境

1.宿主环境的概念 2.宿主环境组成 2.1通信模型 2.2小程序的启动过程 2.3页面渲染过程

2023年高教社杯 国赛数学建模思路 - 案例:FPTree-频繁模式树算法

文章目录 算法介绍FP树表示法构建FP树实现代码 建模资料 ## 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 算法介绍 FP-Tree算法全称是FrequentPattern Tree算法&#xff0c;就是频繁模式树算法&#xff0c…