本文介绍了如何从阻塞上下文(C ++ Actor Framework)访问基于类的actor的状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想通过使用常规类方法暴露当前状态,从阻塞上下文访问基于类的actor的状态。什么是最好的方法?我可以想到三个主要途径:

I'd like to access a class-based actor's state from a blocking context by exposing the current state via regular class methods. What's the best approach? I can think of three main avenues:


  1. 基于类的actors不应该暴露他们的状态,除非消息传递错误的开头)

  2. 类方法应使用 scoped_actor 向基于类的actor发送消息,返回响应。

  3. 类方法应绕过actor框架,只需访问保存状态的成员变量。

  1. Class-based actors should not expose their state except by message passing (i.e. I'm doing something wrong to begin with)
  2. The class method(s) should use a scoped_actor to send a message to the class-based actor and return the response.
  3. The class method(s) should bypass the actor framework and simply access the member variable holding the state.

我尝试了方法#2,但是我确实想出了如何添加'mutable'关键字来修改捕获的变量,我无法成功地延迟方法返回直到捕获的变量可以

I attempted approach #2, but while I did figure out how to add the 'mutable' keyword to modify a captured variable, I was unable to successfully delay the method return until the captured variable could be set without creating deadlock.

方法3似乎适用于下面包含的示例。保护和未保护的访问权限似乎都有效,因此我不确定是否需要保护对状态的访问。

Approach #3 seems to work for the example I've included below. Both guarded and unguarded access seemed to work, so I'm not sure if access to the state needs to be protected.

using size_atom = atom_constant<atom("size")>;
using done_atom = atom_constant<atom("done")>;
using a_type = typed_actor<
    replies_to<int>::with<void>,
    replies_to<size_atom>::with<size_t>,
    replies_to<done_atom>::with<void>>;

class A : public a_type::base
{
public:
    size_t size_direct_access()
    {
        return this->m_values.size();
    }

    size_t size_protected_access()
    {
        lock_guard<mutex> lock(this->m_mutex);
        return this->m_values.size();
    }
protected:
    behavior_type make_behavior() override
    {
        return
        {
            [this](int value)
            {
                lock_guard<mutex> lock(this->m_mutex);
                this->m_values.push_back(value);
            },
            [this](size_atom) -> size_t
            {
                lock_guard<mutex> lock(this->m_mutex);
                return this->m_values.size();
            },
            [this](done_atom)
            {
                this->quit();
            }
        };
    }
private:
    vector<int> m_values;
    mutex m_mutex;
};

void tester()
{
    a_type testeeActor = spawn_typed<A, detached>();
    abstract_actor* abstractActor = actor_cast<abstract_actor*, a_type>(testeeActor);
    A* a = dynamic_cast<A*>(abstractActor);
    scoped_actor self;
    self->sync_send(testeeActor, 5).await(
        [a, testeeActor, &self]()
        {
            size_t direct_access = a->size_direct_access();
            size_t protected_access = a->size_protected_access();
            aout(self) << "Direct: " << direct_access << " Protected: " << protected_access << endl;

            self->sync_send(testeeActor, 3).await(
                [a, testeeActor, &self]()
            {
                size_t direct_access = a->size_direct_access();
                size_t protected_access = a->size_protected_access();
                aout(self) << "Direct: " << direct_access << " Protected: " << protected_access << endl;

                self->sync_send(testeeActor, 1).await(
                    [a, testeeActor, &self]()
                {
                    size_t direct_access = a->size_direct_access();
                    size_t protected_access = a->size_protected_access();
                    aout(self) << "Direct: " << direct_access << " Protected: " << protected_access << endl;

                    self->sync_send(testeeActor, done_atom::value);
                });
            });
        });
}

int main()
{
    cout << "Spawning actors" << endl;
    tester();
    cout << "Awaiting all actors done" << endl;
    await_all_actors_done();
    cout << "Shutdown" << endl;
    shutdown();
    cout << "Press Enter to continue" << endl;
    cin.get();
}


推荐答案

参与者仅通过消息传递进行通信。你不应该试图违反这个原则。否则,运行时提供的所有安全保证都将消失。如果你想共享,可变状态,actor模型是你的错误原语。

Actors communicate only via message passing. You should not try to violate this principle. Otherwise all safety guarantees provided by the runtime are gone. If you want shared, mutable state, the actor model is the wrong primitive for you.

也就是说,共享 immutable 演员模型。您可以将const引用传递到actor构造函数中,以与外部作用域共享状态,但是必须确保引用在actor的生命周期内保持有效。另一种选择是只使用消息,通过为其元素提供一个写入时复制接口,封装了共享的不可变数据的概念。

That said, shared immutable state works fine in the actor model. You can pass a const-reference into the actor constructor to shared state with the outer scope, but then have to ensure that the reference remains valid for the lifetime of an actor. Another option would be to just use messages, which encapsulate the notion of shared, immutable data by providing a copy-on-write interface to its elements.

Upleveling:如果你发现自己需要访问来自演员的数据,您应该重新访问您的程序的设计。

Upleveling: if you find yourself in need of accessing data from an actor, you should probably revisit the design of your program.

这篇关于如何从阻塞上下文(C ++ Actor Framework)访问基于类的actor的状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-01 08:35