我需要一个可以中止的 sleep()
方法(如 here 或 here 所述)。
我的方法是让 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/