как преждевременно прервать time.sleep()
Как преждевременно прервать time.sleep() который приостановил скрипт?
Источник: Stack Overflow на русском
Как преждевременно прервать time.sleep() который приостановил скрипт?
Bсем спасибо за отклик. Я кажется нашел альтернативу но с использыванием потоков.
import threading
import time
e = threading.Event()
# задача выполняется в отдельном потоке
def periodic_task():
while True:
e.wait(timeout=None)
# do some stuff
print('задача завершена!')
e.clear() # --> `.clear()` работает как `.reset()`
t = threading.Thread(target=periodic_task)
t.start()
# основной поток
while True:
time.sleep(5)
e.set()
Например что то типа этого
import queue, threading, time
class Sleep:
def __init__(self, q=None):
self.queue = q or queue.Queue()
self.timeout = 0
def __call__(self, timeout):
"""вызвать ожидание timeout"""
try:
timeout = self.queue.get(timeout=timeout)
except queue.Empty:
return True # ожидание закончено
else:
if timeout:
return self(timeout=timeout) # изменить уже установленное ожидание timeout
return False # ожидание прервано
def change_sleep(self, timeout=0):
"""изменить уже установленное ожидание timeout"""
self.queue.put(timeout)
def func_1(sleep):
while True:
print(1, time.ctime())
sleep(10)
continue
return
def func_2(sleep):
while True:
print(2, time.ctime())
sleep(15)
continue
return
if __name__ == '__main__':
sleep1 = Sleep()
sleep2 = Sleep()
threading.Thread(target=func_1, args=[sleep1]).start()
threading.Thread(target=func_2, args=[sleep2]).start()
time.sleep(2)
sleep1.change_sleep(timeout=0) # следующий цикл func_1 должен был выполнится через 10 сек. но выполнится немедленно
sleep2.change_sleep(timeout=2) # следующий цикл func_2 должен был выполнится через 15 сек. но выполнится через 2 сек
out:
1 Wed Apr 26 13:40:41 2023
2 Wed Apr 26 13:40:41 2023
1 Wed Apr 26 13:40:43 2023 <<- следующий цикл func_1 должен был выполнится через 10 сек. но выполнится немедленно
2 Wed Apr 26 13:40:45 2023 <<- следующий цикл func_2 должен был выполнится через 15 сек. но выполнится через 2 сек
1 Wed Apr 26 13:40:53 2023
2 Wed Apr 26 13:41:00 2023
...
Не знаю питона, но оказыватся, простой перехват сигнала (в Linux, в духе Си) вполне работает
#!/usr/bin/env python
import signal
import sys
import time
def signal_handler(sig, frame):
pass # do nothing (thanks to @andreymal)
# print('You pressed Ctrl+C!')
signal.signal(signal.SIGINT, signal_handler)
print('Press Ctrl+C')
time.sleep(5)
print('OK');