我已经在examples/curl/curl_fuse.cpp和libcaf_core/test/stateful_actor.cpp中读到了stateful_actor的一些用法.它似乎stateful_actor
可以通过声明字段来绑定某些演员的状态State struct
.这非常有用.
我们可以将状态声明为字段class-based actor
以获得相同的效果吗?或者在stateful_actor
(例如线程安全访问)中有一些特殊处理?
以下示例中的actor是否提供相同的功能?
/* Class based actor */ struct ClassCounter : caf::event_based_actor { caf::behavior make_behavior() override { return { [=](inc_atom){ i += 1; } , [=](ret_atom){ return i; } }; } const char* name() const override { return "I am class-based"; } int i = 0; }; /* Stateful actor */ struct CounterState { caf::local_actor* self; int i = 0; const char* name = "I am stateful"; }; caf::behavior StatefulCounter(caf::stateful_actor* self) { return { [=](inc_atom){ self->state.i += 1; } , [=](ret_atom){ return self->state.i; } }; };
neverlord.. 5
我们可以将状态声明为字段
class-based actor
以获得相同的效果吗?或者在stateful_actor
(例如线程安全访问)中有一些特殊处理?
CAF的运行时假定actor是孤立的,即只允许actor本身访问其状态.因此,对actor的状态的访问永远不会同步.演员间通信使用消息传递,从而通过设计避免竞争条件.
有状态的actor允许程序员编写更少的类(因此更少的样板代码),但是ClassCounter
和StatefulCounter
:变量的生命周期之间也存在一个显着的差异.在ClassCounter
,成员变量i
一直存在,直到ClassCounter
调用析构函数.由于actor是引用计数的,因此析构函数会在没有引用它的情况下运行,即不存在对actor的处理actor
或actor_addr
处理.在StatefulCounter
,CounterState
如果actor被初始化并且如果它终止则被销毁,则构造该成员.
只要演员活着,国家才存在.这对于打破循环特别有用.如果你有两个演员A
和B
,你,如果有一个周期A
持有至基准B
通过一个成员变量,反之亦然.使用有状态的演员来打破这个循环.A
将B
在退出时自动释放其引用,反之亦然.
我们可以将状态声明为字段
class-based actor
以获得相同的效果吗?或者在stateful_actor
(例如线程安全访问)中有一些特殊处理?
CAF的运行时假定actor是孤立的,即只允许actor本身访问其状态.因此,对actor的状态的访问永远不会同步.演员间通信使用消息传递,从而通过设计避免竞争条件.
有状态的actor允许程序员编写更少的类(因此更少的样板代码),但是ClassCounter
和StatefulCounter
:变量的生命周期之间也存在一个显着的差异.在ClassCounter
,成员变量i
一直存在,直到ClassCounter
调用析构函数.由于actor是引用计数的,因此析构函数会在没有引用它的情况下运行,即不存在对actor的处理actor
或actor_addr
处理.在StatefulCounter
,CounterState
如果actor被初始化并且如果它终止则被销毁,则构造该成员.
只要演员活着,国家才存在.这对于打破循环特别有用.如果你有两个演员A
和B
,你,如果有一个周期A
持有至基准B
通过一个成员变量,反之亦然.使用有状态的演员来打破这个循环.A
将B
在退出时自动释放其引用,反之亦然.