asyncio - 多少个协同程序?

时间:2018-04-04 20:45:22

标签: python python-asyncio janusgraph goblin

我已经在python应用程序中苦苦挣扎了几天,我希望在文件夹中查找一个或多个文件,并遍历每个文件及其中的每个记录,并创建要保存在Janusgraph上的对象数据库。我正在使用的特定OGM要求与数据库的事务是使用asyncio以异步方式完成的。我已经阅读了很多博客,关于asyncio的帖子,我想我理解异步,等待,任务等的概念......在我的应用程序中,我已经定义了几个处理处理的不同部分的函数:

  • 检索所有可用文件的列表
  • 选择一个文件进行处理
  • 遍历所选文件并读取行/记录以进行处理
  • 接收记录,确定解析from in并调用其他几个负责创建Model对象的函数,然后再将它们保存到数据库中。例如,我创建了不同的功能:User,Session,Browser,DeviceUsed,Server等......

我理解(我可能错了)使用asyncio的最大好处是对函数的调用通常会阻塞I / O,数据库事务,网络延迟等等......

所以我的问题是,我是否需要将所有我的函数转换为协同程序并安排运行事件循环,或者只是阻塞的函数,比如将事务提交到数据库。我尝试这种方法开始并遇到各种各样的问题。

1 个答案:

答案 0 :(得分:4)

  

所以我的问题是,如果我需要将所有我的函数转换为协同程序并计划运行事件循环,或者只是那些会阻塞的函数,

您可能需要转换其中大部分内容,但转换应该主要是机械转换,煮沸至def更改为async def,并在调用其他协同程序时添加await

显然,您无法通过切换到相应的asyncio API或使用loop.run_in_executor()来替换那些没有的实时阻止实际阻止的那些。 (DNS解析曾经是后者的一个突出例子。)

但是你还需要转换他们的调用者,因为除非函数实现类似事件循环的功能,否则从阻塞函数调用协程是没有用的。另一方面,当从另一个协程调用协程时,一切都有效,因为挂起会自动传播到链的顶部。一旦整个调用链由协同程序组成,顶级的调用链就会使用loop.create_task()loop.run_until_complete()进入事件循环。

当然,既不阻塞也不调用阻塞函数的便捷函数可以安全地保持非异步,并且可以通过同步或异步代码调用而没有任何区别。

<小时/> 以上适用于asyncio,它实现了无堆栈协程。 greenlet使用了一种不同的方法,其任务封装了调用堆栈,允许它们在使用普通函数调用的代码中的任意位置进行切换。然而,Greenlets比协同程序更重量级,更不便携,因此我首先转换为asyncio。