python - 如何在 Tornado 中实现可中断的 time.sleep?

标签 python python-3.x asynchronous concurrency tornado

我正在编写一个进程(称为请求进程),它将定期发送 HTTP 请求,但可以被另一个线程/进程(称为主进程)中断随时。最初,我使用线程池处理带有 multiprocessing.Event 对象的请求,以便在发送下一个请求之前等待适当的延迟:

# in the main process
poison_pill_event= multiprocessing.Event()

# pass "poison_pill_event" to the requesting process

# in the requesting process which sends requests every wait_interval seconds
poison_pill_event.wait(timeout=time_interval)

这将允许我拥有一个可中断的 time.sleep() 版本,以防我需要终止进程。否则,它将允许代码在超时后继续运行。

最近,我发现考虑到我所需的吞吐量和资源,异步设计是更合适的替代方案,并且我尝试使用 Tornado。使用 gen.sleep 开始作为非阻塞等待,但它不能被中断。 然后切换到使用 Toro.Event's wait function允许中断。但是,Toro.Event 的 delay 与 multiprocessing.Event 的 timeout 不同,因为它会引发超时异常,从而停止执行。另外,我不相信我可以在进程之间共享它,所以我现在正在尝试将我的主进程与请求进程合并,但这应该不会太困难。

所以我的问题是如何重新模拟我在 Tornado 中使用 multiprocessing.Event.wait 时的行为?

最佳答案

您不再需要 Toro。 Tornado 4.2 及更高版本包含 Toro 的所有功能。

尝试这样的事情,使用条件而不是事件:

import datetime
import logging

from tornado import gen, options
from tornado.ioloop import IOLoop
from tornado.locks import Condition

condition = Condition()


@gen.coroutine
def waiter():
    for _ in range(10):
        yield condition.wait(timeout=datetime.timedelta(seconds=1))
        logging.info("Tick")


@gen.coroutine
def notifier():
    yield gen.sleep(4.5)
    logging.info("Notify")
    condition.notify()


@gen.coroutine
def runner():
    # Yield two Futures; wait for waiter() and notifier() to finish.
    yield [waiter(), notifier()]


options.parse_command_line()  # Configures logging.
IOLoop.current().run_sync(runner)

您会看到如下日志输出:

[I 160712 12:00:28 foo:15] Tick
[I 160712 12:00:29 foo:15] Tick
[I 160712 12:00:30 foo:15] Tick
[I 160712 12:00:31 foo:15] Tick
[I 160712 12:00:31 foo:21] Notify
[I 160712 12:00:31 foo:15] Tick
[I 160712 12:00:32 foo:15] Tick
[I 160712 12:00:33 foo:15] Tick
[I 160712 12:00:34 foo:15] Tick
[I 160712 12:00:35 foo:15] Tick
[I 160712 12:00:36 foo:15] Tick

请注意,在记录“Notify”的那一秒,有两个“Ticks”,否则 Ticks 每秒只发生一次。

关于python - 如何在 Tornado 中实现可中断的 time.sleep?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38333579/

相关文章:

python - django socketio - SocketIOHandler 错误

python - 如何将在 Python 中创建的 bool 值传递给 MongoDB?

python - 如何从 Python 中的字符串中删除空格?

python - 从网站抓取某些字段时无法继续单击下一页按钮

java - 在外部调用中使用 Spring @Async 的任何理由

python - Oauth 配置文件格式 youtube 到 reddit 视频机器人

python - Python 中 float 到分数的转换

django - <class 'astromatchapp.report.admin.user.ReportUserAdmin'> 中定义的 Action 的 __name__ 属性必须是唯一的

javascript - 使用回调 Javascript 在多个函数中获取多个数据

python - (有)python socketserver 相对于常规套接字对象的性能优势吗?