9.4 微线程—Stackless Python
Stackless Python是Python的一个增强版本。Stackless Python修改了Python的代码,提供了对微线程的支持。微线程是轻量级的线程,与前边所讲的线程相比,微线程在多个线程间切换所需的时间更多,占用资源也更少。
9.4.1 Stackless Python概述
Stackless Python不是必需的,它只是Python的一个修改版本,对多线程编程有更好的支持。如果在对线程应用有较高的要求时可以考虑使用Stackless Python来完成。
1.Stackless Python安装
在安装Stackless Python之前应该先安装Python,根据所安装的Python版本到Stackless Python的官方网站http://www.stackless.com下载相应的版本。对于Windows有预编译好的Stackless Python。以Python 2.5为例,下载相应的Stackless Python版本的压缩包,安装步骤如下所示。
(1)将压缩包中的python25.dll及python25_d.dll复制到Windows安装目录下的system32目录中,替换原有的python25.dll及python25_d.dll。注意在替换前应将原始的文件做好备份,以便在出现错误时恢复。
(2)将压缩包中libs目录中的文件复制到Python安装目录下的libs目录中,替换原有的文件。
(3)将压缩包中Lib目录中的文件复制到Python安装目录下的Lib目录中,替换原有的文件。
安装完成后可以在Python的交换式环境中输入如下所示代码。
import stackless
如果没有错误产生,则表示Stackless Python已经安装好了。若出现错误,则可能是Stackless Python与当前的Python版本不兼容,可以考虑使用其他版本的Python。
2.stackless模块中的tasklet对象
Stackless Python提供了stackless内置模块。stackless模块中的tasklet对象完成了与创建线程类似的功能。使用tasklet对象可以像创建线程运行函数那样来运行函数。以下实例使用tasklet对象的部分方法运行函数。
>>> import stackless # 导入stackless模块
>>> def show(): # 定义show函数
... print 'Stackless Python'
...
>>> st = stackless.tasklet(show)() # 调用tasklet添加函数,第2个括号为函数参数
>>> st.run() # 调用run方法,执行函数
Stackless Python
>>> st = stackless.tasklet(show)() # 重新生成st
>>> st.alive # 查看其状态
True
>>> st.kill() # 调用kill方法结束线程
>>> st.alive # 查看其状态
False
>>> stackless.tasklet(show)() # 直接调用tasklet
<stackless.tasklet object at 0x011DD3F0>
>>> stackless.tasklet(show)()
<stackless.tasklet object at 0x011DD570>
>>> stackless.run() # 调用模块的run方法
Stackless Python
Stackless Python
3.stackless模块中的schedule对象
stackless模块中的schedule对象可以控制任务的执行顺序。当有多个任务时,可以使用schedule对象使其依次执行。如下代码使用schedule对象控制任务顺序。
>>> import stackless # 导入stackless模块
>>> def show(): # 定义show函数
... stackless.schedule() # 使用schedule控制任务顺序
... print 1
... stackless.schedule()
... print 2
...
>>> stackless.tasklet(show)() # 调用tasklet,生成任务列表
<stackless.tasklet object at 0x011CF830>
>>> stackless.tasklet(show)()
<stackless.tasklet object at 0x011DD570>
>>> stackless.run() # 执行任务
1
1
2
2
4.stackless模块中的channel对象
使用stackless模块中的channel对象可以在不同的人之间进行通信,这和线程间的通信类似。使用channel对象的send方法可以发送数据。使用channel对象的receive方法可以接收数据。
>>> import stackless # 导入stackless模块
>>> def send(): # 定义send方法
... chn.send('Stackless Python') # 调用channel对象的send方法发送数据
... print 'I send: Stackless Python'
...
>>> def rec(): # 定义rec方法
... print 'I receive:',chn.receive() # 调用channel对象的receive方法接收数据
...
>>> stackless.tasklet(send)() # 调用tasklet,生成任务列表
<stackless.tasklet object at 0x011DD6B0>
>>> stackless.tasklet(rec)()
<stackless.tasklet object at 0x011DD570>
>>> stackless.run() # 执行任务
I receive: Stackless Python
I send: Stackless Python
9.4.2 使用微线程
使用Stackless Python的内置模块stackless也可以完成多线程编程,使用起来更加方便。以下S_P_C.py脚本将前边生产者与消费者的代码改写为Stackless版,代码更加简洁。
# -*- coding:utf-8 -*-
# file: S_P_C.py
#
import stackless # 导入stackless模块
import Queue # 导入Queue模块
def Producer(i): # 定义生产者
global queue # 声明为全局Queue对象
queue.put(i) # 向队列中添加数据
print 'Producer',i, 'add',i
def Consumer(): # 定义消费者
global queue
i = queue.get() # 从队列中取出数据
print 'Consumer',i, 'get',i
queue = Queue.Queue() # 生成队列对象
for i in range(10):
stackless.tasklet(Producer)(i) # 添加生产者任务
for i in range(10):
stackless.tasklet(Consumer)() # 添加消费者任务
stackless.run() # 执行任务
运行脚本后输出如下所示。
Producer 0 add 0
Producer 1 add 1
Producer 2 add 2
Producer 3 add 3
Producer 4 add 4
Producer 5 add 5
Producer 6 add 6
Producer 7 add 7
Producer 8 add 8
Producer 9 add 9
Consumer 0 get 0
Consumer 1 get 1
Consumer 2 get 2
Consumer 3 get 3
Consumer 4 get 4
Consumer 5 get 5
Consumer 6 get 6
Consumer 7 get 7
Consumer 8 get 8
Consumer 9 get 9
Stackless Python是Python的一个增强版本。Stackless Python修改了Python的代码,提供了对微线程的支持。微线程是轻量级的线程,与前边所讲的线程相比,微线程在多个线程间切换所需的时间更多,占用资源也更少。
9.4.1 Stackless Python概述
Stackless Python不是必需的,它只是Python的一个修改版本,对多线程编程有更好的支持。如果在对线程应用有较高的要求时可以考虑使用Stackless Python来完成。
1.Stackless Python安装
在安装Stackless Python之前应该先安装Python,根据所安装的Python版本到Stackless Python的官方网站http://www.stackless.com下载相应的版本。对于Windows有预编译好的Stackless Python。以Python 2.5为例,下载相应的Stackless Python版本的压缩包,安装步骤如下所示。
(1)将压缩包中的python25.dll及python25_d.dll复制到Windows安装目录下的system32目录中,替换原有的python25.dll及python25_d.dll。注意在替换前应将原始的文件做好备份,以便在出现错误时恢复。
(2)将压缩包中libs目录中的文件复制到Python安装目录下的libs目录中,替换原有的文件。
(3)将压缩包中Lib目录中的文件复制到Python安装目录下的Lib目录中,替换原有的文件。
安装完成后可以在Python的交换式环境中输入如下所示代码。
import stackless
如果没有错误产生,则表示Stackless Python已经安装好了。若出现错误,则可能是Stackless Python与当前的Python版本不兼容,可以考虑使用其他版本的Python。
2.stackless模块中的tasklet对象
Stackless Python提供了stackless内置模块。stackless模块中的tasklet对象完成了与创建线程类似的功能。使用tasklet对象可以像创建线程运行函数那样来运行函数。以下实例使用tasklet对象的部分方法运行函数。
>>> import stackless # 导入stackless模块
>>> def show(): # 定义show函数
... print 'Stackless Python'
...
>>> st = stackless.tasklet(show)() # 调用tasklet添加函数,第2个括号为函数参数
>>> st.run() # 调用run方法,执行函数
Stackless Python
>>> st = stackless.tasklet(show)() # 重新生成st
>>> st.alive # 查看其状态
True
>>> st.kill() # 调用kill方法结束线程
>>> st.alive # 查看其状态
False
>>> stackless.tasklet(show)() # 直接调用tasklet
<stackless.tasklet object at 0x011DD3F0>
>>> stackless.tasklet(show)()
<stackless.tasklet object at 0x011DD570>
>>> stackless.run() # 调用模块的run方法
Stackless Python
Stackless Python
3.stackless模块中的schedule对象
stackless模块中的schedule对象可以控制任务的执行顺序。当有多个任务时,可以使用schedule对象使其依次执行。如下代码使用schedule对象控制任务顺序。
>>> import stackless # 导入stackless模块
>>> def show(): # 定义show函数
... stackless.schedule() # 使用schedule控制任务顺序
... print 1
... stackless.schedule()
... print 2
...
>>> stackless.tasklet(show)() # 调用tasklet,生成任务列表
<stackless.tasklet object at 0x011CF830>
>>> stackless.tasklet(show)()
<stackless.tasklet object at 0x011DD570>
>>> stackless.run() # 执行任务
1
1
2
2
4.stackless模块中的channel对象
使用stackless模块中的channel对象可以在不同的人之间进行通信,这和线程间的通信类似。使用channel对象的send方法可以发送数据。使用channel对象的receive方法可以接收数据。
>>> import stackless # 导入stackless模块
>>> def send(): # 定义send方法
... chn.send('Stackless Python') # 调用channel对象的send方法发送数据
... print 'I send: Stackless Python'
...
>>> def rec(): # 定义rec方法
... print 'I receive:',chn.receive() # 调用channel对象的receive方法接收数据
...
>>> stackless.tasklet(send)() # 调用tasklet,生成任务列表
<stackless.tasklet object at 0x011DD6B0>
>>> stackless.tasklet(rec)()
<stackless.tasklet object at 0x011DD570>
>>> stackless.run() # 执行任务
I receive: Stackless Python
I send: Stackless Python
9.4.2 使用微线程
使用Stackless Python的内置模块stackless也可以完成多线程编程,使用起来更加方便。以下S_P_C.py脚本将前边生产者与消费者的代码改写为Stackless版,代码更加简洁。
# -*- coding:utf-8 -*-
# file: S_P_C.py
#
import stackless # 导入stackless模块
import Queue # 导入Queue模块
def Producer(i): # 定义生产者
global queue # 声明为全局Queue对象
queue.put(i) # 向队列中添加数据
print 'Producer',i, 'add',i
def Consumer(): # 定义消费者
global queue
i = queue.get() # 从队列中取出数据
print 'Consumer',i, 'get',i
queue = Queue.Queue() # 生成队列对象
for i in range(10):
stackless.tasklet(Producer)(i) # 添加生产者任务
for i in range(10):
stackless.tasklet(Consumer)() # 添加消费者任务
stackless.run() # 执行任务
运行脚本后输出如下所示。
Producer 0 add 0
Producer 1 add 1
Producer 2 add 2
Producer 3 add 3
Producer 4 add 4
Producer 5 add 5
Producer 6 add 6
Producer 7 add 7
Producer 8 add 8
Producer 9 add 9
Consumer 0 get 0
Consumer 1 get 1
Consumer 2 get 2
Consumer 3 get 3
Consumer 4 get 4
Consumer 5 get 5
Consumer 6 get 6
Consumer 7 get 7
Consumer 8 get 8
Consumer 9 get 9