在Twisted中使用线程(Using Threads in Twisted) -- JerryMarx [2004-08-03 02:38:44]

1. 介绍(Introduction)

Before you start using threads, make sure you do at the start of your program:

使用线程之前,请在程序开始包含如下代码

   1 from twisted.python import threadable
   2 threadable.init()

This will make certain parts of Twisted thread-safe so you can use them safely. However, note that most parts of Twisted are not thread-safe.

这样可以使Twisted中的某些部分变成线程安全的,你可以安全的使用它们.然而要注意的是:Twisted中的大部分代码并不是线程安全的.

2. 以线程安全的方式运行(Running code in a thread-safe manner)

Most code in Twisted is not thread-safe. For example, writing data to a transport from a protocol is not thread-safe. Therefore, we want a way to schedule methods to be run in the main event loop. This can be done using the function twisted.internet.interfaces.IReactorThreads.callFromThread:

Twisted中的大部分代码并不是线程安全的.例如:在protocol中写数据到transport就不是线程安全的.因此,我们想要一种可以在主事件循环中调度方法的途径.可以使用这个函数:twisted.internet.interfaces.IReactorThreads.callFromThread:

   1 from twisted.internet import reactor
   2 from twisted.python import threadable
   3 threadable.init(1)
   4 
   5 def notThreadSafe(x):
   6      """do something that isn't thread-safe"""
   7      # ...
   8 
   9 def threadSafeScheduler():
  10     """Run in thread-safe manner."""
  11     reactor.callFromThread(notThreadSafe, 3) # will run 'notThreadSafe(3)'
  12                                              # in the event loop

3. 在线程中运行(Running code in threads)

Sometimes we may want to run methods in threads - for example, in order to access blocking APIs. Twisted provides methods for doing so using the IReactorThreads API (twisted.internet.interfaces.IReactorThreads). Additional utility functions are provided in twisted.internet.threads. Basically, these methods allow us to queue methods to be run by a thread pool.

有时我们想要在一个线程中运行方法--例如:访问会阻塞的API函数.Twisted在IReactorThreads(twisted.internet.interfaces.IReactorThreads)提供了这样做的方法.还有一些工具函数在twisted.internet.threads中提供.基本上,这些方法允许我们对方法进行排队安排它们运行在线程池.

For example, to run a method in a thread we can do:

例如:我们可以这样使一个方法运行在一个线程中.

   1 from twisted.internet import reactor
   2 
   3 def aSillyBlockingMethod(x):
   4     import time
   5     time.sleep(2)
   6     print x
   7 
   8 # run method in thread
   9 reactor.callInThread(aSillyBlockingMethod, "2 seconds have passed")

4. 工具方法(Utility Methods)

The utility methods are not part of the twisted.internet.reactor APIs, but are implemented in twisted.internet.threads.

工具方法并不是twisted.internet.reactor的一部分,而是在twisted.internet.threads.

If we have multiple methods to run sequentially within a thread, we can do:

如果我们想要多个方法在一个线程中顺序执行,我们可以这样做:

   1 from twisted.internet import threads
   2 
   3 def aSillyBlockingMethodOne(x):
   4     import time
   5     time.sleep(2)
   6     print x
   7 
   8 def aSillyBlockingMethodTwo(x):
   9     print x
  10 
  11 # run both methods sequentially in a thread
  12 commands = [(aSillyBlockingMethodOne, ["Calling First"], {})]
  13 commands.append((aSillyBlockingMethodTwo, ["And the second"], {}))
  14 threads.callMultipleInThread(commands)

For functions whose results we wish to get, we can have the result returned as a Deferred:

如果我们想得到函数的返回值,我们可以让它返回Deferred:

   1 from twisted.internet import threads
   2 
   3 def doLongCalculation():
   4     # .... do long calculation here ...
   5     return 3
   6 
   7 def printResult(x):
   8     print x
   9 
  10 # run method in thread and get result as defer.Deferred
  11 d = threads.deferToThread(doLongCalculation)
  12 d.addCallback(printResult)

5. 管理线程池(Managing the Thread Pool)

The thread pool is implemented by twisted.python.threadpool.ThreadPool.

线程池在twisted.python.threadpool.ThreadPool中实现

We may want to modify the size of the threadpool, increasing or decreasing the number of threads in use. We can do this do this quite easily:

我们也许想要改变线程池的大小,增加或者减少可用线程的数目,很容易做到:

   1 from twisted.internet import reactor
   2 
   3 reactor.suggestThreadPoolSize(30)

The default size of the thread pool depends on the reactor being used; the default reactor uses a minimum size of 5 and a maximum size of 10. Be careful that you understand threads and their resource usage before drastically altering the thread pool sizes.

线程池的缺省大小取决于选择的是那种reactor;缺省reactor使用的最小值是5最大值是10.当你确实要改变线程数之前先确认你知道自己在做什么.

  • 翻译 -- Jerry Marx

(目录)Index

Version: 1.3.0