python actor_转向 Actor 模式

前提:有多线程知识

我对这种模式有点疑问,思维转不过来,于是记录如下:

=====================================

Actor 每个是独立的对象。

Actor 之间通过消息通信。

"actor之间的通信是单向和异步的。因此,消息发送者不知道消息是什么时候被发送, 也不会接收到一个消息已被处理的回应或通知。"

Actor 每个应该有一个消息队列(邮箱),队列的操作需要线程安全。

使用者不需要关心锁,Actor 模式是“简单”的。

上面链接的示例代码不够明朗,精简后:

from queue import Queue

from threading import Thread

import time

class Actor:

def __init__(self):

self._mailbox = Queue()

def send(self, msg):

self._mailbox.put(msg)

def _recv(self):

return self._mailbox.get()

def start(self):

t = Thread(target=self._run)

t.daemon = True

t.start()

def stop(self):

p.send('Exit')

def _run(self):

while True:

msg = self._recv()

print('Got:', msg)

if msg is 'Exit':

break

# Sample use

p = Actor()

p.start()

p.send('Hello')

p.send('World')

p.stop()

p.send('Hello')

# 方便测试

time.sleep(1)

actor 最少只需要一个 send 方法。

其他方法一般通过调用 send 封装对外,方便使用,不是必要的。

只要 send 是线程安全的, 消息处理是 actor 自己内部处理,没线程同步问题。

胜在简单安全。

Actor 应该有个标识/地址。

actor 可以在远程主机上,需要一个逻辑上的地址标识。

个人感觉,一般用不上。

阻塞

外部线程调用 actor send 不会阻塞,但 actor 内部(循环)可能会阻塞。

按照一般的过程思维,既然异步,怎么获得处理结果?TODO:

没找到明朗方案,个人认为:

合适的方案:处理结果发给某个 Actor。

不适合的方案:实现 result 方法并调用(查询),感觉模型变味了,万一 actor 内部阻塞了就影响外部了。

其他

使用 Actor 模型比较著名的是 Erlang 。

会联想到微服务+RPC。

个人认为 Actor 模式测试和调试也方便,通过 Actor 地址发送消息去测试。

对比 CSP 模型

CSP 的 chanel 类似 Actor 的 mailbox,但是独立出来;

chanel 缓冲区为0或有限个,发送消息后,如果接收方一直不接收,会阻塞(即使有缓冲区也会用完);而Actor 邮箱容量是无限的(理论上)。

golang 例子

import (

"time"

)

func worker1(limit int, c chan int) {

for i := 0; i < limit; i++ {

x :=

fmt.Println("worker1",x,i)

time.Sleep(300*1000*1000)

c

}

// close(c)}

func worker2(limit int, c chan int) {

for i := 0; i < limit; i++ {

x :=

fmt.Println("worker2",x,i)

time.Sleep(300*1000*1000)

c

}

// close(c)}

func test28() {

c := make(chan int)

go worker1(5, c)

go worker2(5, c)

c

time.Sleep(3000*1000*1000)

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一个Actor任务通常涉及以下步骤: 1. 定义Actor类:首先,你需要定义一个Actor类,该类应该继承自`multiprocessing.Process`类。在该类中,你需要覆盖`__init__`方法和`run`方法。`__init__`方法用于初始化Actor对象,而`run`方法用于执行Actor任务。 2. 实现Actor任务:在`run`方法中实现Actor任务,可以使用多线程和多进程等技术来完成任务。 3. 启动Actor任务:一旦Actor类定义完成并且Actor任务实现完成,你可以实例化Actor对象并启动Actor任务。通过调用Actor对象的`start`方法,可以启动Actor任务。 以下是一个简单的Actor任务的Python示例代码: ```python import multiprocessing class MyActor(multiprocessing.Process): def __init__(self, name): super().__init__() self.name = name def run(self): print(f"{self.name} started") # do some work here print(f"{self.name} finished") if __name__ == '__main__': actor1 = MyActor("Actor1") actor2 = MyActor("Actor2") actor1.start() actor2.start() actor1.join() actor2.join() ``` 在这个示例中,我们定义了一个名为`MyActor`的Actor类,它继承自`multiprocessing.Process`类。在`MyActor`类中,我们覆盖了`__init__`方法和`run`方法。在`__init__`方法中,我们初始化了Actor对象的名称。在`run`方法中,我们实现了Actor任务,它简单地打印Actor名称和一些文本。在`if __name__ == '__main__':`代码块中,我们实例化了两个Actor对象并启动它们的任务。最后,我们调用了`join`方法以等待Actor任务完成。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值