python - 如何在 APScheduler 中使用 Tornado?

标签 python multithreading concurrency tornado apscheduler

我正在运行 python 的 apscheduler 并定期想做一些工作 POST-ing 到一些 http 资源,这将涉及使用 tornado 的 AsyncHttpClient 作为计划作业。每个工作都会做几个 POST。当每个 http 请求响应时,都会调用回调(我认为 Tornado 使用 future 来完成此操作)。

我在这里关注线程安全,因为 Apscheduler 在各种线程中运行作业。我一直没能找到一个很好解释的例子来说明在这种情况下如何最好地跨多个线程使用 Tornado 。

如何以这种方式将 apschedulertornado 结合使用?

具体问题:

  1. 使用哪个 tornado ioloop?文档说 AsyncHTTPClient “像魔术一样工作”。好吧,魔术让我害怕。我需要在当前线程中使用 AsyncHTTPClient 还是可以使用主线程(可以指定)?

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

  3. 我不清楚线程完成时会发生什么,但仍有待调用的回调/ future 需要调用。这里有问题吗?

  4. 既然 apscheduler 作为线程在进程中运行,并且 python 有 GIL,那么从主线程有一个 IOLoop 几乎是一样的 - 而不是来自不同线程的多个循环(相对于性能)?

最佳答案

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

  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 是否能很好地与之配合使用(并非所有已知的东西都可以在 PyPy 上运行,老实说我也不了解 Tornado)。如果您的 Tornado 应用程序是网络服务器并使用 Nginx 作为代理和 LB,您可能还拥有多个进程。由于您引入了 apscheduler,我建议使用 IOLoop 的 add_timeout它做的事情与您需要的几乎相同,并且它是 Tornado 的原生版本,可以更好地发挥它的作用。无论如何,回调很难调试。将它与 Python 的线程结合起来,你会搞得一团糟。如果您准备考虑另一种选择,只需将所有异步处理移出这个过程——这会让生活变得更轻松。想想像 celery 这样的东西。

关于python - 如何在 APScheduler 中使用 Tornado?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16389125/

相关文章:

python - 在 Python 中间接调用内置运算符

python - 如何在进程之间共享日期变量 - Multiprocessing python

sql - 在 PostgreSQL 中处理竞争条件

c# - 作为单独实例运行的单例 Azure 函数

java - java当前线程数

java - 从 Web 应用程序并行调用许多不同的 Web 服务

python - json[更多级别] 听写 python

python - 在 Anaconda 上将 Python 更新到 3.9

java - 这是使用 ThreadPoolExecutor 的正确方法吗?

php - 使用CURL与cronjob进行PHP多处理