锦绣良缘 文雨 百度云:在Twisted中使用线程(2)

来源:百度文库 编辑:九乡新闻网 时间:2024/04/27 15:05:13

在Twisted中使用线程。

  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一样的。