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)

功能:

  1. 通过 listen 方法,持续的监听通道上传来的消息。
  2. 通过 processMessage 处理收到的消息。
  3. 通过 notify 方法将收到的结果发送到输出端。
  4. registerOutput 可以添加新加的输出端。
  5. __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()

Leave a Reply