как преждевременно прервать time.sleep()

Рейтинг: 1Ответов: 3Опубликовано: 26.04.2023

Как преждевременно прервать time.sleep() который приостановил скрипт?

Ответы

▲ 1

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()        
▲ 0

Например что то типа этого

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
...
▲ 0

Не знаю питона, но оказыватся, простой перехват сигнала (в 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');