一个使用可管道化pythonic actors支持并发的actor库

guild的Python项目详细描述


python guild是一个基本的流水线演员系统,目前基于
线程和开发人员友好的语法。特别地,它向actor系统引入了2个概念,即后期绑定的概念,以及为了实现流水线而使用
通用名称(或别名)的概念。

会很有用的。



简介/概述
----


目前文档是代码本身。这不是很好的
文档,因此此文件包含guild的概述。



线程使用actors-对象和线程安全方法来表示。
调用一个方法会在入站队列中为在线程内执行。公会参与者也可以有stub actor方法,表示
输出。这些是存根方法,预计会反弹到其他actor上的actor
方法。这些存根方法称为后期绑定
方法。这允许以类似于unix管道的方式创建guild actors管道。


此外,guild actors可以是活动的或被动的。在收到消息之前,反应参与者不执行任何操作。活跃的公会参与者可以通过两种主要方式活跃起来:它可以重复执行
动作,或者更复杂的行为可以使用协同程序
样式的生成器。使用生成器可以以比传统python线程更简单的方式停止guild参与者。最后,所有guild
actors都提供了一个默认的"output"后期绑定方法,以涵盖单个输入、单个输出的常见情况。

最后,guild actors只是python对象和具有附加功能的actors-它是为适应您的代码而设计的,而不是其他的/绕道而行。这篇文章介绍了guild的一些简单用法,以及它与传统角色的不同之处。


获取和安装
——


安装非常简单:




$git clone https://github.com/sparkslabs/guild
$cd guild
$sudo python setup.py install


查看一个网络摄像头
这里要注意的是,我们可以很容易地将其他参与者添加到混音中,以便进行网络服务、录制、分析等。如果我们这样做了,
下面的示例可以按原样重新使用。

首先是代码,然后是简短的讨论。




import pygame,pygame.camera,time
来自guild.actor import*
pygame.camera.init()

class camera(actor):
def gen_process(self):
camera=pygame.camera.camera(pygame.camera.list_cameras()[0])
camera.start()
而true:
产生1
帧=相机。获取图像()
自输出(帧)
时间。睡眠(1.0/50)


类显示(actor):
定义初始(self,size):
超级(display,self)。
自大小=大小

def process_start(self):
self.display=pygame.display.set_mode(self.size)

@actor_method
def show(self,frame):
self.display.blit(frame,(0,0))
pygame.display.flip()

input=show

camera=camera().go()
display=显示(800600)).go()
管道(相机,显示)
时间。睡眠(30)
停止(相机,显示)
等待(相机,显示)


在本例中,相机是活动的参与者。它就在那里,
周期性地从网络摄像头中抓取帧。为此,它使用
生成器作为主回路。这使得
捕获帧以便清晰地表示输出的相当基本的行为。还要注意,这个actor
确实使用了正常的阻塞睡眠功能。

显示actor通过捕获传递的参数来初始化。一旦启动了actor,它的process\u start方法就会被调用,使它能够创建一个显示,然后它会坐下来等待消息。当调用方调用actor方法"show"或其别名"input"时,它们就会到达
。当
发生这种情况时,结果是调用show方法,但使用
线程安全的方式-它只显示图像。

将摄像机输出到显示器
-然后主线程等待30秒-即它允许程序
运行30秒。
-然后摄像机和显示器执行器停止
-主线程等待子线程退出,然后
退出自身。

这可以简化(而且将是),但它表明,即使
参与者没有特定的关闭代码,他们也可以通过这种方式完全关闭。


示例:在多个日志文件中查找事件下面是两个日志文件的示例,grep/输出行与给定模式匹配。特别是,它映射到这种命令行:




$(tail-f x.log&;tail-f y.log)grep pants

此示例显示,当连接到一起时,仍有一些区域将从附加的语法糖中受益。特别是,这个例子应该可以一起写,比如
这个:

::


pipeline(parallel(follow("x.log"),follow("y.log"),
grep("pants"),
printer()).run()

.

再次,首先是代码,然后是讨论。





me
self.f=none

def gen_process(self):
self.f=f=file(self.filename)
f.seek(0,2)seek to end
而true:
yield 1
line=f.readline()
如果不是line:no数据,所以等待
时间。睡眠(0.1)
其他:
自我。输出(行)

def onstop(self):
如果self.f:
self.f.close()


类grep(actor):
def初始(self,pattern):
super(grep,self)./>def输入(self,line):
sys.stdout.write(line)
sys.stdout.flush()

follow1=follow("x.log").go()
follow2=follow("y.log").go()
grep=grep("pants").go()
printer=printer().go()

pipeline(follow1,grep,printer)
管道(follow2,grep)
等待键盘中断()
停止(follow1,follow2,grep,打印机)
等待(follow1,follow2,grep,printer)

正如您所看到的,就像bash示例一样,我们有两个actor
跟踪/跟踪两个不同的日志文件。这两个参数都输入到与给定模式匹配的同一个
"grep"actor中,最后这些参数被传递给打印机actor以供显示。每一个演员都会稍微表现出公会模式的不同方面。

-**follow**是一个活跃的演员。它捕获要跟随初始化器的文件名,并为关联的文件句柄创建一个占位符。它们的主循环跟随文件,当文件有一行时调用其output
方法。最后,它将继续执行此操作,直到调用
its.stop()方法为止。如果是,生成器将被终止
(通过传入StopIteration异常),并调用actor的
onStop方法,允许actor关闭文件。

-**grep**是一个简单的反应actor,具有一些设置。尤其是,
它接受提供的模式,使用它编译regex匹配器。
然后对其输入方法的任何actor调用都会导致任何匹配行
通过其输出方法传递。

-**printer**是一个简单的反应actor。任何参与者调用其input
方法都会将传入的数据发送到stdout。

work-in-progress
^^^^^^^^^^^^^^^^


**值得注意的是,guild目前还不是一个成熟的库
,****但是对于许多任务来说,它非常有用。**特别是,
一个区域guild将在指定coord方面有所改进。更加紧凑。例如,相机示例可以变成:

::


pipeline(camera(),display((800600))。run()


这是一个正在进行的工作,但是,添加其他机箱和kamaelia的其他有用部分。

什么是actors?
-------


actors是带有邮箱的线程,允许它们接收和处理
消息。在上面的网络摄像头示例中,它有两个线程,一个用于
捕获图像,另一个用于显示。来自网络摄像头的图像最终会出现在显示器的邮箱中,该邮箱显示它接收到的图像。通常
actor库通过线程对象上的方法将消息发送到actor的邮箱
的操作结束。


以上示例通过修饰的方法演示了这一点:

-display.show,grep.input,printer.input

传入的参数及其函数并放在
参与者的邮箱(线程安全队列)上。然后,actor有一个主循环
,它检查这个邮箱并在线程中执行该方法。

guild与actor模型有何不同?
---------------------------


在传统的actor模型中,camera actor中的代码可能看起来像这样:





import pygame,pygame.camera,time
from guild.actor import*
pygame.camera.init()

类camera(actor):
def\uu init(self,display):
super(camera,self).self.display.show(frame)
time.sleep(1.0/50)

-**注意:这在guild中是完全有效的。**如果您不想使用后期绑定方法或管道的思想,那么它可以像任何其他actor库一样使用。

将事物连接在一起的启动代码现在需要看起来像这样:







display=display((800600)).go()
camera=camera(display).go()
时间。睡眠(30)
停止(相机,显示器)
等待(相机,显示器)

然而,我们的
相机对象的目的地现在已经嵌入到对象
初始化中,而且它也变得更加复杂,灵活性零增加。事实上,我认为您已经失去了灵活性,但我将把
原因留到稍后再谈。

例如,假设我们想将图像记录到磁盘,我们可以通过添加第三个actor来实现
,它可以位于其他actor的中间:




import time,os
class framestore(actor):
def初始化(self,directory='images',base='snap'):
super(framestore,self)。self.directory=directory
self.base=base
self.count=0

def进程启动(self):
os.makedir(self.directory)
尝试:
os.makedirs("images")
除了oserror,如果e.errno!=17:raise

@actor_method
def input(self,frame):
self.count+=1
now=time.strftime("%y%m%d-%h%m%s",time.localtime())
filename=%s/%s-%s-%05d.jpg"%(self.directory,self.base,now,self.count)
pygame.image.save(frame,filename)
self.output(frame)

显示)
时间。睡眠(30)
停止(相机、帧存储、显示)
等待(相机、帧存储、显示)


正是因为这个原因,guild支持延迟绑定的actor方法。


/>类actor(对象):

@late_bind_safe
def output(self,*argv,**argd):
pass


这意味着每个actor都有可用的"output"作为后期绑定actor
方法。

显示)

play.input对于我们来说-这意味着做
camera.output和做self.display.show的效率一样高-
但要灵活得多。

这有很多附加的好处-最好在后面的文章中讨论,但这确实最好地说明了guild不同于通常的演员模式。


为什么要编写和发布这个?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

2013年末/2013年初,我正在进行一个项目,目的是调查与物联网有关的各种想法。(在
具体来说,这个定义对我们来说真的很重要,为什么,以及它提供了什么选项)


作为这个项目的一部分,我编写了一个小的/刚刚够大的库
适合测试我在kamaelia中集成一些思想的一些想法
和语法糖在演员模型里。本质上,
将kamaelia的收件箱和消息映射到传统actor方法,
将发件箱映射到后期绑定actor方法。使用标准名称和/或
别名将允许流水线操作。

guild就是这样的结果,它在几个
项目中被证明是有用的,因此它的打包是一个独立的库。像所有这些
的东西一样,这是一个正在进行的工作,但它也有一个更干净的使用
版本的kamaelia的stm代码,并包括一些e更有用的
组件,如管道和背板。

如果您觉得有用或发现错误,请告诉我。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
javascript如何找到socket。同一局域网上的IO服务器?   将Java代码格式化为Word/RTF格式   java学习对象以及如何将分配的变量封装到私有变量   java Websocket客户端不在Tomcat中工作   java如何在点击按钮时打开本机表情键盘?   java使用哪个Maven GlassFish插件?   Eclipse Java构建路径不允许添加外部JAR   继承Java6集合。勾选适当的用法   JavaApacheDateUtils:使用多个模式解析日期   java hibernate如何生成查询?   具有id或链接的java Dropbox下载文件或文件夹   java模态对话框未在PrimeFaces 5上显示   java将类对象转换为人类可读的字符串   更新数据库中字段的java通用方法   java无法通过Apache Tomcat访问网络文件夹