美文网首页
Python3:让不支持async的函数实现异步操作

Python3:让不支持async的函数实现异步操作

作者: 沧海一声笑的DIY宇宙 | 来源:发表于2019-11-09 12:49 被阅读0次

asyncio是Python3引入的异步IO功能,主要是在语言层面上解决IO阻塞的问题。

常规的用法是在主函数中运行run_until_complete这个函数。但是有的时候,代码中使用的第三方库也需要在主函数中运行自己的循环函数,比如PyQt。那么run_until_complete这个函数就无法调用了。

我尝试了下创建一个新的loop对象,在线程中调用loop对象的循环函数,解决了这个问题。

# 创建一个loop循环

new_loop = asyncio.new_event_loop()

# 定义线程函数

def Loop(loop):

    while True:

        try:

            loop.run_forever()    # 这里调用了asynicio的循环函数

        except KeyboardInterrupt:    # 按ctrl-c能退出

            loop.close()

# 创建一个线程,在线程里面执行 run_forever

t = threading.Thread(target = Loop, args=(new_loop,))

t.daemon = True

t.start()

while True: # 这里是模拟其他库的阻塞函数

    pass

在上面的代码里面,创建好了异步调用的流程,接下来是如何调用不支持asyncio的函数。拿requests来举例吧。

requests是python下常用的web请求库。我们知道http请求是很费时的,调用一次几十到几百毫秒的阻塞。

现在实现一个异步的请求:

def PostFinishTask(action_id):

    asyncio.run_coroutine_threadsafe(PostFinishTaskAsync(action_id), new_loop)

用到的变量是刚才创建的new_loop对象,表示本次异步调用会在刚创建的线程里面执行,不会阻塞主线程。

async def PostFinishTaskAsync(action_id):

    payload = { 'action_id': action_id }    # 模拟的一些网络参数

    def Do_post(): # 为了解决传参的问题,定义一个内部函数

        return requests.post("https://some_call_url", data = payload)

    future = new_loop.run_in_executor(None, Do_post) 

    response = await future # 等待调用完成

这个PostFinishTaskAsync函数才是真正干活的函数。首先加上async,然后为了解决run_in_executor无法给它回调的函数传多个参数,额外的定义了一个Do_post函数用来绕过。

经过以上改造,requests变成了非阻塞的调用了。

本文解决了两个问题,一个是如何自定义一个asyncio的loop循环。另一个是如何把阻塞函数改成非阻塞。虽然Python是一个很慢的语言,但是将IO改造成非阻塞,在一定的场合下还是能工作的不错。

相关文章

  • Python3:让不支持async的函数实现异步操作

    asyncio是Python3引入的异步IO功能,主要是在语言层面上解决IO阻塞的问题。 常规的用法是在主函数中运...

  • ES6 async 同步异步操作

    正如我之前的那篇关于Promise的介绍, async可以让你的异步操作变得更加简单。 异步操作 async函数返...

  • JS Generator 备忘与异步操作

    Generator 函数 异步操作和Async函数

  • 模拟异步函数

    异步函数实现机制(async.js) 实现了支持同步函数和异步函数的声明 声明异步函数 调用异步函数

  • async 函数(转载)

    async 函数 含义 ES2017 标准引入了 async 函数,使得异步操作变得更加方便。 async 函数是...

  • async 函数

    含义 基本用法 语法 async 函数的实现原理 与其他异步处理方法的比较 实例:按顺序完成异步操作 异步遍历器

  • ES6——异步操作

    async 函数 ES2017 标准引入了 async 函数,使得异步操作变得更加方便。async 函数是什么?一...

  • ES7新增属性——async函数

    async函数是什么?只要函数名之前加上async关键字,就表明该函数内部有异步操作。该异步操作应该返回一个pro...

  • 25- async 异步函数

    1、什么是 async 函数? ES2017 标准引入了 async 函数,使得异步操作变得更加方便。async ...

  • async函数用法

    async await ES2017 标准引入了 async 函数,使得异步操作变得更加方便。async 函数是什...

网友评论

      本文标题:Python3:让不支持async的函数实现异步操作

      本文链接:https://www.haomeiwen.com/subject/dblbbctx.html