6

我正在运行 pythonapscheduler并定期希望对一些 http 资源进行 POST 处理,这将涉及使用 tornadoAsyncHttpClient作为计划作业。每个工作都会做几个 POST。当每个 http 请求响应时,就会调用一个回调(我认为 Tornado 使用 afuture来完成此操作)。

我在这里关心线程安全,因为Apscheduler在各种线程中运行作业。我还没有找到一个解释清楚的例子,说明在这种情况下如何最好地跨多个线程使用龙卷风。

我怎样才能以这种方式最好地使用apschedulerwith tornado

具体问题:

  1. 使用哪个龙卷风 ioloop?文档说AsyncHTTPClient“像魔术一样工作”。好吧,魔法吓到我了。我需要AsyncHTTPClient在当前线程中使用还是可以使用主线程(可以指定)?

  2. 关于我使用的 ioloop,我的回调是否存在线程安全问题?

  3. 我不清楚当一个线程完成时会发生什么,但仍有一个待处理的回调/未来需要被调用。这里有问题吗?

  4. 由于 apscheduler 是作为进程内线程运行的,而 python 具有 GIL,那么从主线程拥有一个 IOLoop 与来自不同线程的多个循环(就性能而言)相反吗?

4

1 回答 1

3
  1. Tornado 的所有实用程序都围绕 Tornado 的 IOLoop 工作 - 这也包括 AsyncHTTPClient。并且 IOLoop 不被认为是线程安全的。因此,从运行主 IOLoop 的线程以外的任何线程运行 AsyncHTTPClient 都不是一个好主意。有关如何使用 IOLoop 的更多详细信息,请阅读此

  2. 如果您使用tornado.ioloop.IOLoop.instance(),那么如果您的意图不是向主线程的 IOLoop 添加回调,那么我想您会这样做。您可以使用tornado.ioloop.IOLoop.current()正确的线程来正确引用正确的 IOLoop 实例。而且您将不得不做太多的簿记才能从另一个非主线程的 IOLoop 添加回调到非主线程的 IOLoop - 它会变得太混乱。

  3. 我不太明白这个。但按照我的理解,有两种情况。您正在谈论带有 IOLoop 或没有 IOLoop 的线程。如果线程没有运行 IOLoop,那么在线程完成任何操作后,IOLoop 在其他线程(可能是主线程)中必须执行的任何回调都将被执行。另一种情况是您正在谈论的线程正在运行 IOLoop。除非您停止 IOLoop,否则该线程将不会完成。因此,回调的执行实际上取决于您何时停止 IOLoop。

  4. 老实说,我认为在 Tornado 中使用线程并没有多大意义。除非您在 PyPy 上运行,否则不会有任何性能提升,我不确定 Tornado 是否能很好地使用它(并不是所有的东西都可以在它上面工作,老实说我也不知道 Tornado)。如果您的 Tornado 应用程序是网络服务器并使用 Nginx 作为代理和 LB,那么您也可能有多个进程。既然你已经引入了apscheduler,我建议使用 IOLoop 的add_timeout它与您需要的功能几乎相同,并且它是 Tornado 的原生功能,可以更好地使用它。无论如何,回调很难调试。将它与 Python 的线程结合起来,你可能会遇到很多麻烦。如果您准备考虑另一种选择,只需将所有异步处理移出此过程 - 这将使生活更轻松。想想像芹菜这样的东西。

于 2014-07-02T20:01:06.103 回答