|
521.
|
|
|
Let's assume our <code class="python">largeFibonnaciNumber</code> function from above is in a third party library (returning the result of the calculation, not a Deferred) and is not easily modifiable to be finished in discrete blocks. This example shows it being called in a thread, unlike in the earlier section we'll see that the operation does not block our entire program:
|
|
|
type: Content of: <html><body><p>
|
|
|
|
让我们假设上面的 <code class="python">largeFibonnaciNumber</code> 函数就是这样的一个第三方库中的阻塞函数(返回计算结果而不是 Deferred )并且不容易被修改成在多个块中完成。跟前面不同,这个例子可以将函数放在一个线程中运行而不会阻塞整个程序。
|
|
Translated and reviewed by
Liu, Kun
|
|
|
|
Located in
howto/gendefer.xhtml:222
|
|
522.
|
|
|
def largeFibonnaciNumber():
"""
Represent a long running blocking function by calculating
the TARGETth Fibonnaci number
"""
TARGET = 10000
first = 0
second = 1
for i in xrange(TARGET - 1):
new = first + second
first = second
second = new
return second
from twisted.internet import threads, reactor
def fibonacciCallback(result):
"""
Callback which manages the largeFibonnaciNumber result by
printing it out
"""
print "largeFibonnaciNumber result =", result
# make sure the reactor stops after the callback chain finishes,
# just so that this example terminates
reactor.stop()
def run():
"""
Run a series of operations, deferring the largeFibonnaciNumber
operation to a thread and performing some other operations after
adding the callback
"""
# get our Deferred which will be called with the largeFibonnaciNumber result
d = threads.deferToThread(largeFibonnaciNumber)
# add our callback to print it out
d.addCallback(fibonacciCallback)
print "1st line after the addition of the callback"
print "2nd line after the addition of the callback"
if __name__ == '__main__':
run()
reactor.run()
|
|
|
type: Content of: <html><body><pre>
|
|
|
represents a line break.
Start a new line in the equivalent position in the translation.
|
|
|
represents a space character.
Enter a space in the equivalent position in the translation.
|
|
|
|
def largeFibonnaciNumber():
"""
一个需要长时间运行的阻塞函数,求第 TARGET 个 Fibonnaci 数
"""
TARGET = 10000
first = 0
second = 1
for i in xrange(TARGET - 1):
new = first + second
first = second
second = new
return second
from twisted.internet import threads, reactor
def fibonacciCallback(result):
"""
回调函数,打印 largeFibonnaciNumber 的结果
"""
print "largeFibonnaciNumber result =", result
# 在回调链处理完成后终止 reactor,
# 这样才能让例子程序结束运行
reactor.stop()
def run():
"""
Run a series of operations, deferring the largeFibonnaciNumber
operation to a thread and performing some other operations after
adding the callback
"""
# get our Deferred which will be called with the largeFibonnaciNumber result
d = threads.deferToThread(largeFibonnaciNumber)
# add our callback to print it out
d.addCallback(fibonacciCallback)
print "1st line after the addition of the callback"
print "2nd line after the addition of the callback"
if __name__ == '__main__':
run()
reactor.run()
|
|
Translated and reviewed by
Liu, Kun
|
|
|
|
Located in
howto/gendefer.xhtml:230
|
|
523.
|
|
|
Possible sources of error
|
|
|
type: Content of: <html><body><h2>
|
|
|
|
(no translation yet)
|
|
|
|
Located in
howto/gendefer.xhtml:277
|
|
524.
|
|
|
Deferreds greatly simplify the process of writing asynchronous code by providing a standard for registering callbacks, but there are some subtle and sometimes confusing rules that you need to follow if you are going to use them. This mostly applies to people who are writing new systems that use Deferreds internally, and not writers of applications that just add callbacks to Deferreds produced and processed by other systems. Nevertheless, it is good to know.
|
|
|
type: Content of: <html><body><p>
|
|
|
|
(no translation yet)
|
|
|
|
Located in
howto/gendefer.xhtml:279
|
|
525.
|
|
|
Firing Deferreds more than once is impossible
|
|
|
type: Content of: <html><body><h3>
|
|
|
|
(no translation yet)
|
|
|
|
Located in
howto/gendefer.xhtml:287
|
|
526.
|
|
|
Deferreds are one-shot. You can only call <code>Deferred.callback</code> or <code>Deferred.errback</code> once. The processing chain continues each time you add new callbacks to an already-called-back-to Deferred.
|
|
|
type: Content of: <html><body><p>
|
|
|
|
(no translation yet)
|
|
|
|
Located in
howto/gendefer.xhtml:289
|
|
527.
|
|
|
Synchronous callback execution
|
|
|
type: Content of: <html><body><h3>
|
|
|
|
(no translation yet)
|
|
|
|
Located in
howto/gendefer.xhtml:293
|
|
528.
|
|
|
If a Deferred already has a result available, addCallback <strong>may</strong> call the callback synchronously: that is, immediately after it's been added. In situations where callbacks modify state, it is might be desirable for the chain of processing to halt until all callbacks are added. For this, it is possible to <code>pause</code> and <code>unpause</code> a Deferred's processing chain while you are adding lots of callbacks.
|
|
|
type: Content of: <html><body><p>
|
|
|
|
(no translation yet)
|
|
|
|
Located in
howto/gendefer.xhtml:295
|
|
529.
|
|
|
Be careful when you use these methods! If you <code>pause</code> a Deferred, it is <em>your</em> responsibility to make sure that you unpause it. The function adding the callbacks must unpause a paused Deferred, it should <em>never</em> be the responsibility of the code that actually fires the callback chain by calling <code>callback</code> or <code>errback</code> as this would negate its usefulness!
|
|
|
type: Content of: <html><body><p>
|
|
|
|
(no translation yet)
|
|
|
|
Located in
howto/gendefer.xhtml:302
|
|
530.
|
|
|
Using Perspective Broker
|
|
|
type: Content of: <html><body><h1>
|
|
|
|
(no translation yet)
|
|
|
|
Located in
howto/pb-usage.xhtml:3 howto/pb-usage.xhtml:8
|