StacklessPython简要笔记
StacklessPython简要笔记
作者: | gashero |
---|
1 微进程tasklet
stackless的基本构成单元,一种可调度对象。
1.1 建立微进程对象
示例:
import stackless def print_x(x): print x stackless.tasklet(print_x)('one') stackless.run()
微进程建立后并不运行,直到调用 stackless.run() 才开始运行。
1.2 调度
微进程执行的函数内部可以调用 stackless.schedule() 来暂停当前微进程而把执行权交给执行队列的下一个微进程。
这也是在stackless中实现协程的基本方式。
1.3 轻量级进程
class HackySacker: def __init__(self): #todo... self.channel=stackless.channel() stackless.tasklet(self.messageLoop)() def messageLoop(self): while True: message=self.channel.receive() if message=='exit': return #todo... stackless.schedule() #这里注意要调度一下
执行速度比线程的更快,而且可以允许10000个微进程而不死掉。
2 通道channel
用于微进程之间传递信息和控制微进程的运行流程。可以替代传统线程程序中的Queue模块的互斥队列。
2.1 交换信息
示例:
import stackless channel=stackless.channel() def recv_tasklet(): msg=channel.receive() print msg def send_tasklet(): channel.send('hello')
调用 channel.receive() 时会阻塞当前微进程,等待消息到来。调用 channel.send() 时也会阻塞,直到有微进程读取了消息。
2.2 任务分发
如果一个入口微进程将消息源源不断的发送到通道,而多个工作者微进程等待接受消息,那么每个消息只能被一个微进程所接受,而不是被所有接受。
2.3 事件管理器
使用channel实现的一个基类,用于事件的等待与处理。
class EventHandler: def __init__(self,*outputs): if outputs==None: self.outputs=[] else: self.outputs=list(outputs) self.channel=stackless.channel() stackless.tasklet(self.listen)() def listen(self): while True: val=self.channel.receive() self.processMessage(val) for output in self.outputs: self.notify(output) def processMessage(self,val): pass def notify(self,output): pass def registerOutput(self,output): self.outputs.append(output) def __call__(self,val): self.channel.send(val)
功能:
- 通过 listen 方法,持续的监听通道上传来的消息。
- 通过 processMessage 处理收到的消息。
- 通过 notify 方法将收到的结果发送到输出端。
- registerOutput 可以添加新加的输出端。
- __call__ 可以方便的用对象后加参数来给它发消息。
3 协程coroutine
使用通道实现,两个函数都在循环中等待对方发来的消息。
3.1 乒乓球的例子
import stackless ping_channel=stackless.channel() pong_channel=stackless.channel() def ping(): while ping_channel.receive(): #在此阻塞 #todo... pong_channel.send('from ping') def pong(): while pong_channle.receive(): #todo... ping_channel.send('from pong') stackless.tasklet(ping)() stackless.tasklet(pong)() stackless.tasklet(ping_channel.send)('startup') #启动循环的微进程 stackless.run()