简体   繁体   English

Python,非阻塞线程

[英]Python, non-blocking threads

There are a lot of tutorials etc. on Python and asynchronous coding techniques, but I am having difficulty filtering the through results to find what I need. 关于Python和异步编码技术有很多教程等,但是我很难过滤直通结果来找到我需要的东西。 I am new to Python, so that doesn't help. 我是Python的新手,所以这没有帮助。

Setup 设定

I currently have two objects that look sort of like this (please excuse my python formatting): 我目前有两个看起来像这样的对象(请原谅我的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()

The idea is that the main thread initially draws the screen with incomplete Alphabet objects, fills out the Alphabet objects, updating the screen as they complete. 这个想法是主线程最初用不完整的Alphabet对象绘制屏幕,​​填写Alphabet对象,在完成时更新屏幕。

I've tried a number of implementations of threading.Tread, Queue.Queue, and even futures, and for some reason they either haven't worked, or they have blocked the main thread. 我已经尝试了一些threading.Tread,Queue.Queue甚至是期货的实现,并且由于某种原因他们要么没有工作,要么他们已经阻止了主线程。 so that the initial draw doesn't take place. 这样就不会进行初始抽奖。

A few of the async methods I've attempted: 我试过的一些异步方法:

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)

I ended up writing a thread pool to deal with this use pattern. 我最终编写了一个线程池来处理这种使用模式。 Try creating a queue and handing a reference off to all the worker threads. 尝试创建队列并将引用传递给所有工作线程。 Add task objects to the queue from the main thread. 从主线程向队列添加任务对象。 Worker threads pull objects from the queue and invoke the functions. 工作线程从队列中拉出对象并调用这些函数。 Add an event to each task to be signaled on the worker thread at task completion. 在任务完成时向工作线程上的每个任务添加一个事件。 Keep a list of task objects on the main thread and use polling to see if the UI needs an update. 在主线程上保留任务对象列表,并使用轮询查看UI是否需要更新。 One can get fancy and add a pointer to a callback function on the task objects if needed. 如果需要,可以获得想象并在任务对象上添加指向回调函数的指针。

My solution was inspired by what I found on Google: http://code.activestate.com/recipes/577187-python-thread-pool/ 我的解决方案受到了我在Google上发现的内容的启发: http//code.activestate.com/recipes/577187-python-thread-pool/

I kept improving on that design to add features and give the threading, multiprocessing, and parallel python modules a consistent interface. 我不断改进该设计以添加功能,并为线程,多处理和并行python模块提供一致的界面。 My implementation is at: 我的实施是:

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

Docs: 文档:

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

If you are new to Python and not familiar with the GIL I suggest doing a search for Python threading and the global interpreter lock (GIL). 如果您不熟悉Python并且不熟悉GIL,我建议您搜索Python线程和全局解释器锁(GIL)。 It isn't a happy story. 这不是一个快乐的故事。 Generally I find I need to use the multiprocessing module to get decent performance. 通常我发现我需要使用多处理模块来获得不错的性能。

Hope some of this helps. 希望有些帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM