Python,非阻塞线程

JoB*_*324 5 python asynchronous python-2.7

关于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()
Run Code Online (Sandbox Code Playgroud)

这个想法是主线程最初用不完整的Alphabet对象绘制屏幕,填写Alphabet对象,在完成时更新屏幕.

我已经尝试了很多线程的实现.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()
Run Code Online (Sandbox Code Playgroud)
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()
Run Code Online (Sandbox Code Playgroud)
def run_async(f, cb):
    pool = Pool(processes=1)
    result = pool.apply_async(func=f, args=args, callback=cb)
Run Code Online (Sandbox Code Playgroud)

Xyc*_*cor 2

我最终编写了一个线程池来处理这种使用模式。尝试创建一个队列并将引用传递给所有工作线程。从主线程将任务对象添加到队列中。工作线程从队列中提取对象并调用函数。向每个任务添加一个事件,以便在任务完成时在工作线程上发出信号。在主线程上保留任务对象列表,并使用轮询来查看 UI 是否需要更新。如果需要的话,我们可以想象一下,在任务对象上添加一个指向回调函数的指针。

\n\n

我的解决方案的灵感来自于我在 Google 上发现的内容: http ://code.activestate.com/recipes/577187-python-thread-pool/

\n\n

我不断改进该设计以添加功能并为线程、多处理和并行 python 模块提供一致的接口。我的实现位于:

\n\n

https://github.com/nornir/nornir-pools

\n\n

文件:

\n\n

http://nornir.github.io/packages/nornir_pools.html

\n\n

如果您是 Python 新手并且不熟悉 GIL,我建议您搜索一下 Python 线程和全局解释器锁 (GIL)。这不是一个快乐的故事。一般来说,我发现我需要使用多处理模块才能获得不错的性能。

\n\n

希望有些帮助。

\n