from queue import Queue from threading import Thread def threaded_task(fn): fn.queue = Queue() def worker(): while True: self, num = fn.queue.get() fn(self, num) fn.queue.task_done() if not getattr(fn, "thread", None): fn.thread = Thread(target=worker, daemon=True).start() def wrapper(*args, **kwargs): print(args, kwargs) if args: self, num = args fn.queue.put((self, num)) if maxsize := kwargs.get("maxsize", None): fn.queue.maxsize = maxsize return wrapper.queue = fn.queue wrapper.fn = fn return wrapper class Job: """Thread executing tasks from a given tasks queue""" @threaded_task def print_number(self, number): print(number) if __name__ == "__main__": import inspect numbers = [i for i in range(1000)] Job.print_number(maxsize=100) jobs = [] for num in numbers: jobs.append((new_job := Job())) new_job.print_number(num) Job.print_number.queue.join()