<p>这里有一种使用更简单的设置代码的方法,没有<code>threading.Event</code>,因为解决问题似乎不需要这样做。基本上,您可以自己创建<code>future_b</code>作为一个新的<code>Future()</code>,并使用<code>future_a</code>上的<code>add_done_callback</code>方法设置<code>future_b</code>的结果。这里,<code>func_a</code>是计算<code>future_a</code>的结果的计算,<code>func_b</code>是使用<code>future_a</code>的结果计算<code>future_b</code>的结果的计算</p>
<pre class="lang-py prettyprint-override"><code>from concurrent.futures import ProcessPoolExecutor, Future
def func_a(x):
return 2 + x
def func_b(x):
return 10 * x
if __name__ == '__main__':
pool = ProcessPoolExecutor(3)
future_a = pool.submit(func_a, 3)
future_b = Future()
future_b.set_running_or_notify_cancel()
def callback(f):
x = f.result()
y = func_b(x)
future_b.set_result(y)
future_a.add_done_callback(callback)
print(future_b.result()) # 50
</code></pre>
<p>如果您想要一个助手函数来完成这项工作,您可以编写一个:<code>map_future</code>接受一个future和一个mapping函数,并根据需要返回新的映射future。此版本在<code>f.result()</code>或<code>func_b</code>抛出异常时处理异常:</p>
<pre class="lang-py prettyprint-override"><code>def map_future(future_a, func):
future_b = Future()
future_b.set_running_or_notify_cancel()
def callback(f):
try:
x = f.result()
y = func(x)
future_b.set_result(y)
except Exception as e:
future_b.set_exception(e)
future_a.add_done_callback(callback)
return future_b
</code></pre>
<p>警告:这与<code>Future</code>类文档中的建议背道而驰,文档中说:</p>
<blockquote>
<p><code>Future</code> instances are created by <code>Executor.submit()</code> and should not be created directly except for testing.</p>
</blockquote>
<p>此外,如果您在回调中有任何不是<code>Exception</code>子类的错误,根据文档,它们将被“记录并忽略”。为了简单起见,我选择在这段代码中只捕获<code>Exception</code>,但是您可能更喜欢捕获所有可能引发的事件的<code>sys.exc_info()[0]</code>方式</p>