# -*- coding: utf-8 -*- """Демо: Process + Queue — ручная организация воркеров. Запуск из корня курса: python lab04_multiprocessing/examples/03_process_queue_demo.py Pool — удобный «конвейер». Process+Queue — ручная схема: воркеры сами берут задачи из очереди. Это основа для producer-consumer в лабе 5. """ import multiprocessing import os import sys import time sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))) def worker(task_q, result_q): """Воркер: берёт задачи, пока не встретит None — «маркер конца».""" name = multiprocessing.current_process().name while True: task = task_q.get() if task is None: result_q.put((name, "done")) break idx, value = task time.sleep(0.05) # «полезная работа» result_q.put((name, f"задача {idx}: {value}² = {value ** 2}")) def main(): ctx = multiprocessing.get_context() task_q = ctx.Queue() result_q = ctx.Queue() n_workers = 3 workers = [ctx.Process(target=worker, args=(task_q, result_q), name=f"воркер-{i}") for i in range(n_workers)] for w in workers: w.start() # кладём задачи for i in range(9): task_q.put((i, i + 1)) # маркеры конца — по одному на воркер for _ in range(n_workers): task_q.put(None) # собираем результаты done = 0 t0 = time.perf_counter() while done < n_workers: name, msg = result_q.get() if msg == "done": done += 1 print(f" [{name}] завершился") else: print(f" [{name}] {msg}") for w in workers: w.join() print(f"время: {time.perf_counter() - t0:.2f} c (9 задач по 0.05 c на 3 воркерах)") if __name__ == "__main__": main()