在Twisted中使用线程
2010-09-22 11:16:02 来源:WEB开发网callInThread 意指在线程中运行,调用该方法需要在主事件循环中,而执行其传入的函数则是在线程中。可以与上一节提供的 callFromThread`结合使用,即在worker线程函数中调用 `callFromThread 提交结果。
3 工具函数
工具函数作为 twisted.internet.reactor 的一部分API提供,但是并不是在 twisted.internet.threads 中实现的。
如果我们有多个方法需要在线程中以队列方式运行,我们可以做:
from twisted.internet import threads
def aSillyBlockingMethodOne(x):
import time
time.sleep(2)
print x
def aSillyBlockingMethodTwo(x):
print x
# 排队后在线程中运行两个方法
commands=[(aSillyBlockingMethodOne,["calling first"])]
commands.append((aSillyBlockingMethodTwo,["and the second"],{}))
threads.callMultipleInThread(commands)
如果我们希望得到函数的运行结果,那么我们可以使用Deferred:
from twisted.internet import threads
def doLongCalculation():
# ... do long calculation here ...
return 3
def printResult(x):
print x
# 在线程中运行,并且通过 defer.Deferred 获取结果
d=threads.deferToThread(doLongCalculation)
d.addCallback(printResult)
如果你希望在reactor线程中调用一个方法,并且获取结果,你可以使用 blockingCallFromThread
from twisted.internet import threads,reactor,defer
from twisted.web.client import getPage
from twisted.web.error import Error
def inThread():
try:
result=threads.blockingCallFromThread(reactor,getPage,"http://twistedmatrix.com/")
except Error,exc:
print exc
else:
print result
reactor.callFromThread(reactor.stop)
reactor.callInThread(inThread)
reactor.run()
blockingCallFromThread 将会返回对象或者抛出异常,或者通过抛出到传递给他的函数。如果传递给它的函数返回了一个Deferred,他会返回Deferred回调的值或者抛出异常到errback。
4 管理线程池
线程池是在 twisted.python.threadpool.ThreadPool 中实现的。
我们可以修改线程池的大小,增加或者减少可用线程的数量,可以这么做:
from twisted.internet import reactor
reactor.suggestThreadPoolSize(30)
缺省的线程池大小依赖于使用的reactor,缺省的reactor使用最小为5个,最大为10个。在你改变线程池尺寸之前,确保你理解了线程和他们的资源使用方式。
在Twisted2.5.0中使用线程
刚才翻译了对应版本8.0.0的Twisted的线程指南,但是我还是在用2.5.0,所以这里只记录与8.0.0的差异,不做重新翻译。
当你开始使用线程之前,确保你在启动程序的时候使用了如下:
from twisted.python import threadable
threadable.init()
这回让Twisted以线程安全的方式初始化,不过仍然注意,Twisted的大部分仍然不是线程安全的。
以线程安全的方式运行代码中初始化多了两行:
from twisted.python import threadable
threadable.init(1)
2.5.0的文档中没有 blockingCallFromThread 的例子。也许根本就没有这个方法。
实际我下载文档的版本是2.4.0,不过应该与2.5.0一样的。
更多精彩
赞助商链接