多线程装饰器解决回调过程中的阻塞问题
本文最后更新于 411 天前,其中的信息可能已经有所发展或是发生改变。

Tkinter的回调函数在运行时是全局阻塞的,这就产生了一个问题,如果回调函数的执行时间很长,就会造成窗口失去响应,相信大家都有所经历,尤其是在Windows平台使用过iTunes的同学。

这个问题怎么解决?很显然,对于每一个回调函数都给一个进程是不现实的,在暂时不使用协程的情况下,很自然的,会给出多线程的解决方案。

多线程,我也不是第一次用了,这是一种很成熟的解决方案,虽然受限于GIL的存在,它并不能充分发挥并行的计算能力;但是在这个场景中,我们需要的是异步,而不是计算,所以在这里使用多线程是一个合理的选择(当然,我认为使用协程更加合理)

那么在业务场景中,对每一个接口函数进行多线程的改写是不现实的,Python提供了一种很棒的语法糖——装饰器来解决这个问题;在有切面需求的场景中,总是可以见到它的身影——Flask的路由,Django的权限控制等等…

而在这个问题中,我们需要的也正是对函数进行包装,以多线程的方式运行这个闭包函数,并在闭包函数内以某种方式获取函数返回值。

某种方式呢?在线程内部回收函数返回值?很自然的,我相信大家都会想到队列。

OK,一切都很清楚了,我们需要封装目标函数,用队列回收函数返回值,用多线程运行闭包的函数,最后一步,用装饰器修饰要运行的函数。

这里有需要注意的一点:装饰器会在函数定义时执行,当然,如果代码没有涉及到这里最好;但是在GUI编程中,对于文章开头讲的那种问题,我们不能让函数在界面还未初始化完成(或者用户还未主动调用)时便运行函数。

怎么办呢?最简单的方法,设置一个标志位,当所有的界面初始化完成之后,将该标志位设为假,在目标函数中加以判断(当然,你可以把这个标志位作为参数传给装饰器,但是这样很怪不是吗?)

还有一个可以考虑的地方:在某些情况下,我们可能并不需要函数的返回值,也就没必要浪费资源去创建一个队列;在这种情况下,我认为对于装饰器设置默认参数是一个不错的选择。

好了,问题都解决了,下面上代码:

# author : [email protected]
# @basic.thread() func() : result
# 通过该函数可以从一个新线程运行一个函数
#
# 思路:
# 开一个新线程并通过队列将函数返回值同步
def thread(resultQueue = None):
    def wrapper(function):
        def proWarp(*args, **kwargs):
            def process(*args, **kwargs):
                ret = function(*args, **kwargs)
                if resultQueue : resultQueue.put(ret)
                return resultQueue
            thread = threading.Thread(target = process,
            args = args, kwargs = kwargs)
            thread.setDaemon(True)
            thread.start()
            return process
        return proWarp
    return wrapper

a = queue.Queue()
@thread(a)
def test(arg):
    print (arg)
    return arg[::-1]
test("Hello World!")
print ("Hello, Fools!")
print (a.get())

这个对目标函数再多一层包装的方法也是我在StackOverflow上问出来的,其实当时我也没想出来…(不够当时也确实就差这一步了)

这是这个问题链接:Python decorator with multithreading

同学们,记得把需要的包引进来。

暂无评论

发送评论 编辑评论


|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇