ACE 中的Active Object模式

news2025/1/19 23:13:35

 Active Object 设计模式:

       1) 根据对象被调用的方式,可以将对象分为两类:

        Passive Object和Active Object。Passive 和 Object和调用者在同一个线程中,这就是我们通常所用的函数调用。而Active Object和调用在不同的线程中,它有自己的控制线程。Active Object设计模式是一种应用于并发编程的设计模式,它通过解耦对象的访问和对象的执行来增加并发性,从而简化对象的同步访问。

        将方法的调用和方法的执行解耦。方法的调用在客户线程中,而方法的执行在另一个独立的线程中。另外,通过良性设计,使得客户端看起来就像是调用一个普通的方法。具体来说:我们用一个Proxy来描述Active Object的接口,由一个Servant来提供Active Object的实现。Proxy和Servant运行在两个不同的线程中,这样方法的调用和方法的执行就可以并发地运行了。其中Proxy运行在客户线程中,而Servant运行在另一个线程中。在运行期,Proxy将客户端的方法调用转化为方法请求,它们通过一个调度器保存在一个请求链表中,调度器运行在Servant线程中,它将方法请求从链表中取出,交由Servant执行。客户还可以获得运行结果。由于方法的调用和运行在不同的线程中,所以运行结果并不是立即返回的。客户只能通过阻塞等待或者循环查询的方式来获得运行结果,这个结果我们用Future来表示。

       2) 在Active Object设计模式中,有6个关键的参与者:

        Proxy:提供一个接口,客户通过该接口调用Active Object的方法。通过Proxy应用程序可以使用强类型的编程语言,而不是线程间松散的消息。Proxy位于客户线程中。

        方法请求(Method Request):方法请求类定义用于执行Active Object方法的接口。客户每次调用Proxy定义的方法,就会构造一个方法请求对象。一个方法请求包含了方法参数等上下文信息,这些上下文信息用于方法的执行和执行结果的返回。

        请求链表:Proxy将具体的方法请求对象插入到请求链表中。请求链表既用于保存方法请求,又用于判断方法请求的可执行性。请求链表将Proxy线程和Servant线程解耦,使得它们可以并发地运行。

        调度器(Scheduler):调度器运行于Active Object线程,用于调度方法请求。调度器使用请求链表来管理方法请求,调度的策略可以根据应用程序的实际需要进行选择。

        工作者(Servant):定义Active Object的行为和状态。工作者实现的方法需要与Proxy 接口、方法请求一致。当方法请求被调度器调度时,工作者的方法才会得到执行,因此,它总是运行在调度器线程中。

        结果(Future):客户通过Proxy调用一个方法,就可以接收到Future。Future使得客户可以获得方法调用的执行结果。由于客户的请求和方法的执行在不同的线程中,所以Future只能通过阻塞等待或者循环查询的方式获取。

       

#include "ace/Log_Msg.h"
#include "ace/OS.h"
#include "ace/Task.h"
#include "ace/Method_Request.h"
#include "ace/Future.h"
#include "ace/Activation_Queue.h"
#include <memory.h>
using namespace std;

#pragma comment(lib,"ace.lib")

// Servant 类对status_result_ 进行简单的累加工作

class Servant
{
public:
    Servant()
    {
        status_result_ = 1;
    }
    int status_update(void) 
    {
        ACE_DEBUG((LM_DEBUG, ACE_TEXT("Obtaining a status_update in %t ") ACE_TEXT("thread of control\n")));
        ACE_OS::sleep(2);
        return next_result_id();
    }
private:
    int next_result_id(void)
    {
        return status_result_++;  
    };
    int status_result_;
};

class StatusUpdate : public ACE_Method_Request
{
public:
    StatusUpdate(Servant & controller, ACE_Future<int>&returnval)
        : controller_(controller), returnVal_(returnval)
    {
        ACE_DEBUG((LM_DEBUG, "StatusUpdate::StatusUpdate.\n"));
    }
    virtual int call(void)
    {
        ACE_DEBUG((LM_DEBUG, "StatusUpdate::call.\n "));
        this->returnVal_.set(this->controller_.status_update());
        return 0;
    }
    
    private:
    Servant& controller_;
    ACE_Future<int> returnVal_;

};

class ExitMethod : public ACE_Method_Request
{
public:
    virtual int call(void)
    {
        return -1;
    }
};

// 调度器类
class Scheduler : public ACE_Task_Base
{
public:
    Scheduler()
    {
        ACE_DEBUG((LM_DEBUG, "Scheduler::Scheduler.\n"));
        this->activate();
    }

    virtual int svc(void)
    {
        ACE_DEBUG((LM_DEBUG, "Scheduler::svc.\n"));
        while(1)
        {
            auto_ptr<ACE_Method_Request>  request
            (this->activation_queue_.dequeue());
            if (request->call() == -1)
                break;
        }
        return 0;
    }

    int enqueue(ACE_Method_Request* request) 
    {
        ACE_DEBUG((LM_DEBUG, "Proxy::status_update.\n"));
        return this->activation_queue_.enqueue(request);
    }
    private:
    ACE_Activation_Queue activation_queue_;
};

        //既然在Active Object设计模式中使用了ACE_Activation_Queue作为消息队列,那么也就没有有必要使用ACE_Task类了,因为ACE_Task使用的消息队列是ACE_Message_Queue。

class Proxy
{
public:
    ACE_Future<int> status_update(void)
    {
        ACE_DEBUG((LM_DEBUG, "Proxy::status_update.\n"));
        ACE_Future<int> result;
        this->scheduler_.enqueue(new StatusUpdate(this->controller_, result));
        return result;
    }
    void exit(void)
    {
         ACE_DEBUG((LM_DEBUG, "Proxy::exit.\n"));
         this->scheduler_.enqueue(new ExitMethod);
    }
    private:
        Scheduler scheduler_;
        Servant controller_;
};

int ACE_TMAIN(int, ACE_TCHAR* [])
{
    Proxy controller;
    ACE_Future<int> results[10];
//客户通过Proxy接口发起累加方法请求
    for (int i = 0; i < 10; i++)
    results[i] = controller.status_update();
    ACE_OS::sleep(5);
//客户获取运行结果
    for (int j = 0; j < 10; j++)
    {
         int result = 0;
         results[j].get(result);
         ACE_DEBUG((LM_DEBUG, "[%D(%t)] result %d\n", result));
    }
    controller.exit();
    ACE_Thread_Manager::instance()->wait();
    return 0;
}  

运行结果如下: 

 

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

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

相关文章

NestJS入门2:创建模块

前文参考&#xff1a; NestJS入门1 1. 创建user模块 在项目目录下输入以下命令 nest g resource user 执行完后会在src文件夹下创建出user文件夹及文件夹下相应的文件&#xff0c;如下 2. 增加打印 3. 测试 &#xff08;1&#xff09;POSTBody Postman 服务端的打印 &…

深度学习(16)--基于经典网络架构resnet训练图像分类模型

目录 一.项目介绍 二.项目流程详解 2.1.引入所需的工具包 2.2.数据读取和预处理 2.3.加载resnet152模型 2.4.初始化模型 2.5.设置需要更新的参数 2.6.训练模块设置 2.7.再次训练所有层 2.8.测试网络效果 三.完整代码 一.项目介绍 使用PyTorch工具包调用经典网络架构…

地下管线管网三维建模工具MagicPipe3D V3.4.2发布

经纬管网建模系统MagicPipe3D&#xff0c;本地离线参数化构建地下管网三维模型&#xff08;包括管道、接头、附属设施等&#xff09;&#xff0c;输出标准3DTiles服务、Obj模型等格式&#xff0c;支持Cesium、Unreal、Unity、Osg等引擎加载进行三维可视化、语义查询、专题分析&…

新版Java面试专题视频教程——框架篇

新版Java面试专题视频教程——框架篇 框架篇 01-框架篇介绍02-Spring-单例bean是线程安全的吗03-Spring-AOP相关面试题04-Spring-事务失效的场景05-Spring-bean的生命周期5.1 BeanDefinition 06-Spring-bean的循环依赖(循环引用)6.1 一般对象的循环依…

算法沉淀——BFS 解决拓扑排序(leetcode真题剖析)

算法沉淀——BFS 解决拓扑排序 01.课程表02.课程表 II03.火星词典 Breadth-First Search (BFS) 在拓扑排序中的应用主要是用来解决有向无环图&#xff08;DAG&#xff09;的拓扑排序问题。拓扑排序是对有向图中所有节点的一种线性排序&#xff0c;使得对于每一条有向边 (u, v)&…

数据结构排序:插入排序、希尔排序、选择排序、冒泡排序、堆排序、快速排序

文章目录 插入排序希尔排序选择排序冒泡排序堆排序快速排序 插入排序 基本思想&#xff1a; 直接插入排序是一种简单的插入排序法&#xff0c;其基本思想是&#xff1a; 把待排序的值按其关键码值的大小逐个插入到一个已经排好序的有序序列中&#xff0c;直到所有的记录插入完…

matlab入门,在线编辑,无需安装matab

matlab相关教程做的很完善&#xff0c;除了B站看看教程&#xff0c;官方教程我觉得更加高效。跟着教程一步一步编辑&#xff0c;非常方便。 阅读 MATLAB 官方教程&#xff1a; MATLAB 官方教程提供了从基础到高级的教学内容&#xff0c;内容包括 MATLAB 的基本语法、数据处理…

AUTOSAR CP--chapter7从CAN网络学习Autosar通信

从CAN网络学习Autosar通信 前言缩写词CAN通信在AUTOSAR架构中的传输上位机配置 第六章总结&#xff1a;学习了如何使用工具的自动配置功能&#xff0c;位我们生成系统描述中部分ecu的BSW模块配置&#xff0c;但是自动配置的功能虽然为我们提供了极大的便利&#xff0c;我们仍然…

Windows 使设置更改立即生效——并行发送广播消息

目录 前言 1 遍历窗口句柄列表 2 使用 SendMessageTimeout 发送延时消息 3 并行发送消息实现模拟广播消息 4 修改 UIPI 消息过滤器设置 5 托盘图标刷新的处理 6 完整代码和测试 本文属于原创文章&#xff0c;转载请注明出处&#xff1a; https://blog.csdn.net/qq_5907…

运筹系列89:anylogic仿真软件入门

1. agent-based simulation 这里概述一下help文档中Supply chain GIS model例子的要点&#xff1a;触发事件的agent和执行任务的agent。 在这个案例中&#xff0c;触发事件的agent是retailer&#xff0c;不断有订单生成&#xff1b;而执行任务的agent是vehicle&#xff0c;不断…

成功解决:× python setup.py egg_info did not run successfully.

执行pip install -r requirements.txt报错 错误信息如下&#xff1a; error: subprocess-exited-with-error python setup.py egg_info did not run successfully.│ exit code: 1╰─> [93 lines of output]解决办法&#xff1a; 更新 setuptools 和 pip pip install -…

比特浏览器bit_selenium3bit_selenium4使用

bit_selenium3 from selenium import webdriver from selenium.common.exceptions import TimeoutException from selenium.webdriver.common.keys import Keys from selenium.webdriver.chrome.options import Options from bit_api import *# /browser/open 接口会返回 selen…

我不允许你还不知道!这些求职常用黑话!

我不允许你还不知道&#xff01;这些求职常用黑话&#xff01; 一. HC、BG、BU、JD、OD、OT&#xff08;公司相关&#xff09;二、岗位相关1、base2、JD3、RD4、QA5、PM6、PR7、PD 三、求职或者薪资1、OC/意向书2、开奖3、泡池子4、保温5、A&#xff08;argue&#xff09;6、总…

数据库的备份模式(完全备份,增量备份,差异备份)

数据库的备份 备份原因 数据的丢失 数据的删除 备份目标 数据的一致性 数据的可用性 备份技术 物理备份/冷备份 直接复制数据库文件&#xff0c;适用于大型数据库环境&#xff0c;不受存储引擎的限制&#xff0c;但不能恢复到不同的MySQL版本。 常用的冷备份工具 ta…

电阻负载柜是什么?

电阻负载柜是用于模拟实际负载的设备&#xff0c;主要用于电力系统、电气设备和电子设备的测试、调试和维护。它通过调节电阻值来改变负载的大小&#xff0c;以满足不同场合的需求。电阻负载柜在电力系统、电气设备和电子设备的测试、调试和维护过程中发挥着重要作用。 电阻负载…

BI 数据分析,数据库,Office,可视化,数据仓库

AIGC ChatGPT 职场案例 AI 绘画 与 短视频制作 PowerBI 商业智能 68集 Mysql 8.0 54集 Oracle 21C 142集 Office 2021实战应用 Python 数据分析实战&#xff0c; ETL Informatica 数据仓库案例实战 51集 Excel 2021实操 100集&#xff0c; Excel 2021函数大全 80集 Excel 2021…

外贸人大部分都复工了吧

这几天是属于国家规定的节后上班时间&#xff0c;估计大部分人都已经开始复工了。作为粤西地区小伙伴中的一员&#xff0c;表示虽然身在广州&#xff0c;心却还在高州&#xff0c;毕竟年例在这些天才刚刚开始&#xff0c;我们那边每年最热闹的时候就是年例了&#xff01; 由于…

XCharts——Unity上最好用的免费开源图表插件!(一)基本介绍

只讲实用干货&#xff01;&#xff01;&#xff01;&#xff08;过于细节的或是未提及到的可直接问&#xff09; 目录 XCharts介绍 插件简介 插件下载 XCharts基本使用 类型介绍 1.折线图&#xff08;LineChart&#xff09; 2.柱形图&#xff08;BarChart&#xff09; …

IBM Spectrum LSF Process Manager 在共享分布式计算环境中运行和管理业务关键工作流程

IBM Spectrum LSF Process Manager 设计、记录和运行复杂的计算工作流 亮点 ● 快速创建复杂的分布式工作流 ● 开发可重复的最佳实践 ● 自信地运行关键工作流程 ● 提高流程可靠性 IBM Spectrum LSF Process Manager 使您能够设计和自动化计算或分析流程&#xff0c; 捕获…

力扣(LeetCode)数据结构练习题(2)

今天又写了两道关于链表的练习题&#xff0c;来给大家分享一下。巩固一下上一篇学到的链表知识&#xff0c;题目可以然我们更清楚的认识链表。 目录 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表 给你单链表的头结点 head &#xff0c;请…