У меня есть декоратор, записанный так:
import threading
from time import sleep
from functools import wraps
import sys
import os
def repeat_periodically(f):
""" Repeat wrapped function every second """
@wraps(f)
def wrap(self, *args, **kwargs):
def wrap_helper(*args, **kwargs):
try:
threading.Timer(1.0, wrap_helper).start()
f(self)
except KeyboardInterrupt:
try:
sys.exit(1)
except:
os._exit(1)
wrap_helper()
return wrap
Я не уверен, что он продолжает открывать новый поток каждый раз, когда он вызывает себя, но, несмотря на это, я не могу убитьпроцесс, когда я нажму CTRL + C
.Я также добавил тот же блок try-except
в украшенную мной функцию:
@repeat_periodically
def get_stats(self):
try:
# log some state information
except KeyboardInterrupt:
try:
sys.exit(1)
except:
os._exit(1)
Моя программа просто продолжает работать, и все, что я вижу в терминале, это
^C <the stuff that I am logging>
<the stuff that I am logging>
<the stuff that I am logging>
Другими словами, он просто продолжает регистрироваться, хотя я пытаюсь убить его с помощью CTRL + C
.
Обновление:
Я должен отметить, чтоописанный выше процесс запускается из другого потока:
tasks = [
{'target': f, 'args': (arg1)},
{'target': g},
]
for task in tasks:
t = threading.Thread(**task)
t.start()
В частности, это вторая задача, которая раскручивает таймер.Однако, если я установлю t.daemon = True
, процесс просто запускается один раз и завершается.Первое задание использует watchdog .Я, по сути, использовал пример кода из документации сторожевого таймера:
def watch_for_event_file(Event):
path = sys.argv[1] if len(sys.argv) > 1 else '.'
event_handler = LoggingCreateHandler(Event)
observer = Observer()
observer.schedule(event_handler, path)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
(извините за все обновления)