python - Python 中的可中止 sleep ()

标签 python thread-sleep

我需要一个可以中止的 sleep() 方法(如 herehere 所述)。

我的方法是让 threading.Event.wait() 在指定的持续时间内超时:

def abortable_sleep(secs, abort_event):
    abort_event.wait(timeout=secs)
    abort_event.clear()

在调用 abortable_sleep(10, _abort) 之后,我现在可以(从另一个线程)调用 _event.set(_abort)abortable_sleep() 在 10 秒之前终止。

例子:

def sleeping_thread():
    _start = time.perf_counter()
    print("%f thread started" % (time.perf_counter() - _start))
    abortable_sleep(5, _abort)
    print("%f thread stopped" % (time.perf_counter() - _start))

if __name__ == '__main__':

    _abort = threading.Event()
    while True:
        threading.Thread(target=sleeping_thread).start()
        time.sleep(3)
        _abort.set()
        time.sleep(1)

输出:

0.000001 thread started
3.002668 thread stopped
0.000002 thread started
3.003014 thread stopped
0.000001 thread started
3.002928 thread stopped
0.000001 thread started

此代码按预期工作,但我仍有一些问题:

  • 难道没有一种更简单的方法来让某事发生吗?像一个可以中止的sleep()
  • 这可以做得更优雅吗?例如。这样我必须小心 Event 实例,它没有绑定(bind)到 abortable_sleep()
  • 实例
  • 我是否必须预料到性能问题会出现while True: abortable_sleep(0.0001)这样的高频循环? wait()-timeout 是如何实现的?

最佳答案

我有一个包装类,它基本上在 Event 之上添加了一些 sleep 语义。好处是你只需要传递一个 Sleep 对象,如果你愿意,你可以多次调用 sleep() (sleep() 不是线程安全的)并且您可以从另一个线程wake()

from threading import Event

class Sleep(object):
    def __init__(self, seconds, immediate=True):
        self.seconds = seconds
        self.event = Event()
        if immediate:
            self.sleep()

    def sleep(self, seconds=None):
        if seconds is None:
            seconds = self.seconds
        self.event.clear()
        self.event.wait(timeout=seconds)

    def wake(self):
        self.event.set()

使用示例:

if __name__ == '__main__':
    from threading import Thread
    import time
    import logging

    logger = logging.getLogger()
    logger.setLevel(logging.DEBUG)
    formatter = logging.Formatter('%(created)d - %(message)s')
    handler = logging.StreamHandler()
    handler.setFormatter(formatter)
    logger.addHandler(handler)

    logger.info("sleep")
    s = Sleep(3)
    logger.info("awake")

    def wake_it(sleeper):
        time.sleep(1)
        logger.info("wakeup!")
        sleeper.wake()

    logger.info("sleeping again")
    s = Sleep(60, immediate=False)
    Thread(target=wake_it, args=[s]).start()
    s.sleep()
    logger.info("awake again")

上面的输出可能是这样的:

1423750549 - sleep
1423750552 - awake
1423750552 - sleeping again
1423750553 - wakeup!
1423750553 - awake again

正是您所做的,但封装在一个类中。

关于python - Python 中的可中止 sleep (),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28478291/

相关文章:

Python3.4读取内容流web请求

python - 精细控制 h5py 缓冲

python - 改进 reCaptcha 2.0 解决自动化脚本(Selenium)

java - 无限循环的线程在捕获一些异常后停止

JavaGame 角色在绘图时移动不准确?

python - Django : Clean unicode for UrlEncoding

Python - 如何提取多个标签之间的元素

c++ - 防止 sleep_for 阻塞后台线程

java - Thread.sleep() 的精确替代方案

java - ReSTLet 服务器的行为类似于单线程