有许多关于Python和异步编码技术的教程等,但是我很难过滤通过结果来找到我需要的东西。我是Python的新手,所以这没有帮助。
我目前有两个看起来像这样的对象(请原谅我的python格式化):
class Alphabet(parent):
def init(self, item):
self.item = item
def style_alphabet(callback):
# this method presumably takes a very long time, and fills out some properties
# of the Alphabet object
callback()
class myobj(another_parent):
def init(self):
self.alphabets = []
refresh()
def foo(self):
for item in ['a', 'b', 'c']:
letters = new Alphabet(item)
self.alphabets.append(letters)
self.screen_refresh()
for item in self.alphabets
# this is the code that I want to run asynchronously. Typically, my efforts
# all involve passing item.style_alphabet to the async object / method
# and either calling start() here or in Alphabet
item.style_alphabet(self.screen_refresh)
def refresh(self):
foo()
# redraw screen, using the refreshed alphabets
redraw_screen()
def screen_refresh(self):
# a lighter version of refresh()
redraw_screen()
这个想法是主线程最初用不完整的Alphabet
对象绘制屏幕,填写Alphabet对象,在完成时更新屏幕。
我已经尝试了一些threading.Tread,Queue.Queue甚至是期货的实现,并且由于某种原因,它们要么没有工作,要么阻止了主线程。这样就不会进行初始抽奖。
class Async (threading.Thread):
def __init__(self, f, cb):
threading.Thread.__init__(self)
self.f = f
self.cb = cb
def run(self):
self.f()
self.cb()
def run_as_thread(f):
# When I tried this method, I assigned the callback to a property of "Alphabet"
thr = threading.Thread(target=f)
thr.start()
def run_async(f, cb):
pool = Pool(processes=1)
result = pool.apply_async(func=f, args=args, callback=cb)
答案 0 :(得分:2)
我最终编写了一个线程池来处理这种使用模式。尝试创建队列并将引用传递给所有工作线程。从主线程向队列添加任务对象。工作线程从队列中拉出对象并调用这些函数。在任务完成时向工作线程上的每个任务添加一个事件。在主线程上保留任务对象列表,并使用轮询查看UI是否需要更新。如果需要,可以想象并在任务对象上添加指向回调函数的指针。
我的解决方案受到我在Google上发现的内容的启发:http://code.activestate.com/recipes/577187-python-thread-pool/
我不断改进该设计,以添加功能并为线程,多处理和并行python模块提供一致的界面。我的实现是:
https://github.com/nornir/nornir-pools
文档:
http://nornir.github.io/packages/nornir_pools.html
如果您是Python新手并且不熟悉GIL,我建议您搜索Python线程和全局解释器锁(GIL)。这不是一个快乐的故事。通常我发现我需要使用多处理模块来获得不错的性能。
希望其中一些有用。