Python,非阻塞线程

时间:2014-02-18 21:04:58

标签: python python-2.7 asynchronous

有许多关于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)

1 个答案:

答案 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)。这不是一个快乐的故事。通常我发现我需要使用多处理模块来获得不错的性能。

希望其中一些有用。