首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >CAF中的参与者参考周期

CAF中的参与者参考周期
EN

Stack Overflow用户
提问于 2022-03-23 14:28:47
回答 1查看 27关注 0票数 1

“用户手册”的手动破断周期部分讨论了参与者之间的相互引用,以及如何避免这些场景中的潜在陷阱。我的问题是,你如何创建一个循环开始?我经常将一个派生函数创建的句柄传递到另一个派生函数的参数中,但我很难弄清楚如何给两个参与者彼此的句柄:

代码语言:javascript
运行
AI代码解释
复制
#include<chrono>
#include<iostream>
#include <vector>
#include <string>

#include "caf/typed_event_based_actor.hpp"
#include "caf/scoped_actor.hpp"
#include "caf/caf_main.hpp"

#include "CustomMessages.h"
#include "../DuckParty/Displayable.h"
#include "../DuckParty/Duck.h"
#include "../DuckLibrary/Mallard.h"
#include "../DuckLibrary/TerminalDisplayer.h"

using namespace std::chrono;
using namespace std;

using DisplayActor = caf::typed_actor<
    caf::result<void>(display_behavior, time_point<system_clock>, string)>;

using DuckActor = caf::typed_actor<
    caf::result<void>(do_duck_behavior)>;

class DisplayState {
private:
    unique_ptr<Displayable> displayable_;

public:
    explicit DisplayState(unique_ptr<Displayable> displayable) : displayable_(move(displayable)) {}

    DisplayActor::behavior_type make_behavior() {
        return {
            [this](display_behavior, time_point<system_clock> quack_time, string behavior) {
                displayable_->DisplayBehavior(quack_time, behavior);
            }
        };
    }
};

using DisplayImpl = DisplayActor::stateful_impl<DisplayState>;


class DuckState {
private:
    DuckActor::pointer self_;
    unique_ptr<Duck> duck_;
    int milliseconds_;
    DisplayActor display_actor_;

public:
    explicit DuckState(DuckActor::pointer self, unique_ptr<Duck> duck, int milliseconds, DisplayActor display_actor) :
        self_(self),
        duck_(move(duck)),
        milliseconds_(milliseconds),
        display_actor_(display_actor) {}

    DuckActor::behavior_type make_behavior() {
        self_->send(self_, do_duck_behavior_v);
        return {
        [this](do_duck_behavior) {
            self_->delayed_send(self_, std::chrono::milliseconds(milliseconds_), do_duck_behavior_v);
            time_point<system_clock> quackTime = system_clock::now();
            self_->send(display_actor_, display_behavior_v, quackTime, duck_->GetFlyBehavior() + " " + duck_->GetNoiseBehavior());
            }
        };
    }
};

using DuckImpl = DuckActor::stateful_impl<DuckState>;

void caf_main(caf::actor_system& sys) {
    unique_ptr<Duck> duck = make_unique<Mallard>("Howard the Duck");
    unique_ptr<Displayable> display = make_unique<TerminalDisplayer>();

    DisplayActor display_actor = sys.spawn<DisplayImpl>(move(display));                 // How to give this actor a strong static reference to duck_actor?
    DuckActor duck_actor = sys.spawn<DuckImpl>(move(duck), 500, display_actor);
}

CAF_MAIN(caf::id_block::duck_msg_types)

您可以在我的main函数中看到,我可以轻松地给DuckActor一个DisplayActor句柄,但是如何也给DisplayActor一个DuckActor句柄呢?您有关于如何创建参考周期的例子或建议吗?恐怕我漏掉了一些明显的东西。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-03-23 23:47:38

您有关于如何创建参考周期的例子或建议吗?

一般的建议是不要创建它们。;)

您已经在用状态类构造应用程序,这是避免问题的推荐方法。要明确的是,两个参与者之间有着相互处理的关系,这本身并不是一个问题,而且一直在发生。消息保存对发送方的引用,这通常导致两个参与者现在相互保持引用。手册警告的周期是永久周期,即使在参与者终止之后也会持续。

如果您使用的是有状态参与者,则没有永久的循环。状态在终止时被破坏,例如,由于调用self->quit()。但是,参与者对象本身不能在此时销毁。参与者被计算为引用,因此底层对象一直存在,直到不再引用它为止。如果两个参与者通过成员变量相互保存引用,则会出现内存泄漏。只有通过直接从一种参与者类型(例如,从event_based_actor继承)派生来实现一个参与者,您才会遇到这个问题。CAF手册和其他资源总是提倡不从参与者类型继承,但是如果您这样做了(因为您遵循了使用状态类的最佳实践),您还需要担心潜在的循环。

至于演员之间如何相互推荐,有两种方法。消息指向发件人,因此,通过以某种方式存储发件人信息,如果发件人仍然持有对接收方的引用,您就创建了一个循环。当然,您也可以在消息中包含一个参与者句柄,然后以这种方式存储它。在上面的例子中,您主要启动了两个参与者。但是,在服务器-工作者关系中,通常会让服务器启动工作人员.如果工作人员出于某种原因需要知道他们的父级,服务器可以将句柄传递给工作人员。因此,在您的情况下,您可以让显示演员产卵鸭子,然后存储鸭演员手柄。

只是为了重新迭代,不需要考虑应用程序中的循环,除非您通过直接从一个CAF参与者类型继承并在成员变量中存储对其他参与者的引用来实现参与者。只要您不这样做,您就可以安全地跳过手动部分,讨论打破循环。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71594825

复制
相关文章
用c++写一个广告系统
用到的基础类库 1、sstream <sstream> 库定义了三种类:istringstream、ostringstream和stringstream,分别用来进行流的输入、输出和输入输出操作。另 外,每个类都有一个对应的宽字符集版本。 简单起见,我主要以stringstream为中心,因为每个转换都要涉及到输入和输出操作。 2、std库   string   list   pair   function   unordered_map mutex lock_guard  多线程加锁,变量作用域范围
架构师刀哥
2018/03/20
7340
【c#搬砖记】用Docx导出word格式的docx文件
DocX开源网址:http://docx.codeplex.com/ 1、引入DocX.dll 调用ReplaceText()方法替换模板中的字符。只支持docx格式的word文档 using (DocX docx = DocX.Load(fileDemo)) { docx.ReplaceText("@某某某", tester.name); docx.ReplaceText("@110101198101010001",
阿炬
2018/05/11
1.6K0
用纯汇编来写strlen一定比C语言写的快吗?
事情是这样的,我在写操作系统,看到田宇大佬写的代码里面,strlen也是用汇编来写的,我很不解,这个不是可以用C来实现吗?难不成纯汇编更快?于是我就写了一个小程序来做实验。看看这两者的速度。
灯珑LoGin
2022/10/31
6130
看图说话用Eclipse写C++
1) Eclipse CDT介绍 Eclipse是开源的IDE中最流行的一个,它本身是一个JAVA程序,也就是说他可以运行在windows/linux/mac os上。由于Eclipse是采用一种叫OSGi的架构(其实是一种微核模型),所以它可以方便的被改造成编写各种语言的IDE。原生的Eclipse支持的是JAVA语言,但是只要增加一个叫CDT的插件(也是官方的),就可以直接编写C/C++程序。同样你也可以增加插件来编写LUA、PYTHON、FLASH AS3以及其他各种流行语言。现在Eclipse社
韩伟
2018/03/05
2.2K0
看图说话用Eclipse写C++
C++ 文件、流《Rice C++ 学习开发》
前面利用了三篇文章讲解了面向过程过程到面向对象语言的转变,以及对C++面向对象的内容进行了讲解,接下来将对C++的高级编程内容进行讲解。
Rice加饭
2022/05/09
6120
C++ 文件、流《Rice C++ 学习开发》
我用C++做开发
C++11标准出来之前,你返回个对象心里都惴惴不安,怕new之后忘了delete,怕内存泄漏,怕影响效率什么的。现在C++11,14标准出来以后,写代码没有那么痛苦了,跟写脚本差不多了。什么rvo copy ellision,各种优化过程都成为标准了,返回对象根本不是问题。还有智能指针加持,一般都很难写出内存泄露的代码来。就拿occt来说,通篇都找不到一个指针操作。以前都说Web开发走速成路线,现在C++开发也是走速成路线。C++你可以写得很精细注重效率,也可以用各种库搞得糙快猛,这就很难得了。尤其是还有Qt等第三方工具的助力,开发效率刚刚的。并且C++嵌入python,就能用python做二次开发,嵌入js ,就能用js做开发。你就是图个方便!
fem178
2020/06/23
8970
c++文件操作之文本文件-写文件
写文本文件步骤:包含头文件:#include<ftream>、创建流对象:ofstream ofs;、打开文件:ofs.open(文本路径,打开方式)、写数据:ofs<<数据、关闭文件:ofs.close()
西西嘛呦
2020/08/26
9210
如何使用 C 或 C++ 获取目录中的文件列表
如何使用 C 或 C++ 获取目录中的文件列表?我的程序不允许使用 ls 这样的命令。
ClearSeve
2022/02/10
8.3K0
c++标准库cstdio文件
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
用户7886150
2021/02/13
8170
写算法,用 C++ 还是用 Java ,差别大吗?
今天带来的文章,是 GitChat 签约作者王晓华在不断被读者吐槽:“好好一本算法书为什么要用 C++ 来写” 时,万般无奈下憋出来的。
用户1737318
2018/12/10
2.8K0
写算法,用 C++ 还是用 Java ,差别大吗?
OpenCV安装方法用C++开发用Python开发
安装环境:Windows8 安装的OpenCV版本:OpenCV3.3 安装所需的其他软件:VS2015
keloli
2018/09/13
6480
利用FlubuCore用C#来写DevOps脚本
随着近些年微服务的流行,有越来越多的开发者和团队所采纳和使用,它的确提供了很多的优势也解决了很多的问题,但是我们也知道也并不是银弹,提供优势的同时它也给我们的开发人员和团队也带来了很多的挑战。
Jlion
2022/04/07
4020
利用FlubuCore用C#来写DevOps脚本
在Linux上用Eclipse写C++程序
我厂很多同学使用VC在windows上编写linux的C/C++程序,然后再传的开发服务器上,然后再编译和调试。如果有修改,可能会直接用vi去改了,然后再把源代码同步回来。其实这样做挺折腾的。也有大神全盘vim设置emacs写,想来也是极好的。 但是,也有另外一个方案,就是在 Linux上安装个写C/C++程序的IDE,这样可以直接编写、编译、运行、上传SVN,非常方便。其实要做到这点,也很简单: 你需要一个虚拟机来运行一个带GUI的LINUX,这样IDE才能运行起来,当然也可以直接在开发服务器上安
韩伟
2018/03/05
3.5K0
在Linux上用Eclipse写C++程序
c++文件操作之二进制文件-写文件
#include<iostream> #include<fstream> #include<string> using namespace std; class Person { public: char name[64]; int age; }; void test() { ofstream ofs; ofs.open("person.txt", ios::out | ios::binary); Person p = { "张三",18 }; ofs.wri
西西嘛呦
2020/08/26
8020
用 powershell 脚本 .ps1 写一个自动化的「编译->链接->运行C++文件」脚本
我这人有个毛病:一定要用 VS Code 写代码,确切地说,一定要用我自己的 VS code ,自己配好的键盘映射、自己的插件。
Piper蛋窝
2021/03/24
1.4K0
如何用c++来写一个九九乘法表
九九乘法表的原理是第一个for循环是控制行数,第二个for循环是控制每行的数据的相乘,例如,i=3时进入第一个for循环,3是小于等于9的,进入第二个for循环,就j=1,t=1*3,j=2,t=2*3,j=3,t=3*3,以此类推。
用户7886150
2021/02/05
2.2K0
C++覆盖或删除指定位置的文件内容
我们经常使用ofstream或者fstream可写文件,使用ifstream可以写文件,但需要设置文件的打开状态为ios::out。C++中IO流打开模式使用位掩码来表示。IO流打开模式有:
恋喵大鲤鱼
2018/08/03
3.9K0
都是用 DllImport?有没有考虑过自己写一个 extern 方法?
发布于 2018-09-06 13:58 更新于 2018-09-06 15:04
walterlv
2018/09/18
7960
都是用 DllImport?有没有考虑过自己写一个 extern 方法?
用 C++ 和 Java 写算法,有差别吗?
我写了七、八年的 “算法博客”,出版了一本《算法的乐趣》,一门《算法应该怎么“玩”?》课程,所有介绍算法的例子都是用 C++ 编写的。
CSDN技术头条
2019/11/19
2.5K0
用 C++ 和 Java 写算法,有差别吗?
C#——写一个控件库
注意:控件的类和部分类(包括窗体生成类/窗体设计类)全部要加public来修饰,不然无法在工具箱里找到
vv彭
2021/02/04
2K0
C#——写一个控件库

相似问题

用C和C++接口写一个库,用哪种方式包装?

90

有没有可以编译C++或C++的库?

50

有没有人尝试过用C或C++为黑莓平台进行开发?

53

有没有更好的方法来写我写的查询

10

用c++写二进制文件

15
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档