使用asyncio在后台运行线程类中的函数

时间:2017-12-12 20:21:36

标签: python python-asyncio

这是我第一次尝试在项目中使用asyncio。我希望我的课程能够初始化并运行,其中一些功能在“后台”定期运行。我希望在启动这些后台任务后,类'init返回,以便它可以继续同时执行同步操作。

我有什么:

 class MyClass(threading.Thread):
  def __init__(self, param):
      self.stoprequest = threading.Event()
      threading.Thread.__init__(self)

      self.param = param

      self.loop = asyncio.new_event_loop()
      asyncio.set_event_loop(self.loop)
      asyncio.ensure_future(self.periodic(), loop=self.loop)

      print("Initialized")

  async def periodic(self):
      while True:
          print("I'm here")
          await asyncio.sleep(1)

  def run(self):
       # continue to do synchronous things

我确信毫不奇怪,这不起作用。我也尝试在init中使用带有asyncio的“普通”run_until_complete()函数,但当然init永远不会返回。

如何在后台定期运行属于此类的asyncio函数,而类的其余部分(run())继续执行同步工作?

1 个答案:

答案 0 :(得分:3)

将循环作为参数传递给ensure_future并不启动此循环。您应该致电run_until_completerun_forever以强制您开始协同程序,没有其他方法可以执行此操作。

  

如何定期运行属于此类的asyncio函数   在后台,而类的其余部分(run())继续做   同步工作?

你不能。就像你不能在主线程中同时运行事件循环和同步代码一样。 Loop starting - 阻止线程的执行流程,直到循环停止。这就是asyncio的工作原理。

如果你想在后台运行asyncio,你应该在单独的线程中运行它,并在主线程中执行同步操作。可以找到如何执行此操作的示例here

你需要在线程中运行阻塞代码与asyncio一起使用最方便的方法是在主线程中运行asyncio并使用run_in_executor在后​​台线程中运行阻塞代码功能。你可以找到这样做的例子here

重要的是,asyncio本身通常用于主线程(没有其他线程)以实现异步编程的好处。你确定你需要第二个线程吗?如果没有,请阅读this answer以了解使用asyncio的原因。