import signal from threading import Thread, Event from queue import Queue def prepend_signal(sig, func): handler = signal.getsignal(sig) def wrapper(*args, **kwargs): func(*args, **kwargs) handler(*args, **kwargs) signal.signal(sig, wrapper) class ProdThread: """ provided func has to accept two arguments: - queue = queue.Queue() - running = threading.Event() """ def __init__(self, func): self.func = func self.thread = None self.queue = Queue() self.running = Event() prepend_signal(signal.SIGINT, self.stop) def target(self): self.running.set() self.func(self.queue, self.running) self.running.clear() def start(self): if not self.thread: self.thread = thread = Thread(target=self.target) thread.start() def stop(self, *args): # signal() gives some extra args self.running.clear() if self.thread: self.thread.join() self.thread = None