【问题标题】:Callback not getting called回调没有被调用
【发布时间】:2015-09-28 01:53:24
【问题描述】:
for x,y in my_dict.iteritems():
     for z in y:
           def done_callback(result):

                code,content=result.get()
                if code==0:
                      if content:
                             new_content.append(content)
                      else:
                             pass
                else:
                      return error_html(environ,start_response,content)


           try:
                    pool.apply_async(function_returns_tuple,(x,z,my_val),done_callback)
           except Exception as e:
                    print e

当我看到 new_content 的值时,它是空的并且还有回调函数 - done_callback 没有被调用。我错过了某些部分吗?

【问题讨论】:

  • “当我看到 new_content 的值”从未在代码中显示,它与问题相关。但这似乎是典型的异步问题。请记住 - 任何异步结果都只能从回调(或回调在堆栈跟踪中的某个位置)访问。您可能喜欢使用concurrent.futures.ThreadPoolExecutor 为您管理异步。
  • new_content 只是一个列表,我在所有这些之外,在所有 for 循环之外检查它。
  • 那么就如我所料。假设您有四个孩子;你告诉他们“我要去上班,但我的手机不见了,所以大家搜索,找到后给我!”然后,而不是等待,你马上去上班。你的一个孩子找到了电话,然后试图把它给你,但你已经不在了。与此同时,你在工作,没有电话,想知道为什么这些天孩子们这么懒惰。
  • 那么如何解决它以使父母和孩子同步?注意:python 2.7

标签: multithreading python-2.7 callback


【解决方案1】:

这是一个最小的工作示例:

from multiprocessing import Pool
from time import sleep

my_dict = { "a": [1, 2], "b": [3] }
my_val = 5

# has to be defined before Pool is created
def processing_function(args):
    (x, y, v) = args     # mapped function only gets one arg; so we unpack
    if y == 2:           # we throw a wrinkle in,
        return ('', '')  # to demonstrate filter
    return ("[Code %s %d %d]" % (x, y, v), "[Content %s %d %d]" % (x, y, v))


pool = Pool(2)    # execute two workers in parallel (feel free to change)

# make an iterator for all your values
inputs = ((x, z, my_val) for (x, y) in my_dict.iteritems() for z in y)
async_results = pool.map_async(processing_function, inputs)
pool.close()      # necessary before pool.join()
pool.join()       # wait for all processes in the pool to finish
results = async_results.get()    # now we can get the results
# we can extract just the results we want...
non_empty_content_joined = ''.join(
        content for (code, content) in results if content != '')
print non_empty_content_joined
# => [Content a 1 5][Content b 3 5]

【讨论】:

  • 感谢您的示例,但我的代码中缺少哪些部分。您能否指出我摘录中的漏洞?
  • join() 将在主线程中等待结果,如果您在主线程中需要它们。
【解决方案2】:

当您在apply_async 中指定回调函数时,回调将在稍后调用。 “异步”部分意味着您可以在 apply 的工作完成之前继续在当前线程上处理您的业务。

在您的示例代码中,您在循环中调用apply_async,但您无需等待任何操作完成。如果您想等待操作完成,则必须保留主线程(例如,通过阻塞或循环)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-26
    • 2013-04-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多