# -*- coding: utf-8 -*- """Демо: предвестник лабы 3 — потоки НЕ ускоряют счёт. Запуск из корня курса: python lab02_threads/examples/03_threads_cpu_demo.py Та же схема, что с sleep, но вместо sleep — счёт. Время не уменьшается: GIL разрешает исполнять байт-код Python только одному потоку. Подробное исследование — лабораторная 3. """ import os import sys import threading import time sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))) def cpu_worker(n: int) -> None: s = 0.0 for i in range(n): s += i ** 0.5 # чистый Python-код: держит GIL return s def run_threads(n_threads: int, n_per_thread: int) -> float: threads = [threading.Thread(target=cpu_worker, args=(n_per_thread,)) for _ in range(n_threads)] t0 = time.perf_counter() for t in threads: t.start() for t in threads: t.join() return time.perf_counter() - t0 def main(): TOTAL = 3_000_000 t0 = time.perf_counter() cpu_worker(TOTAL) t_seq = time.perf_counter() - t0 print(f"1 поток, {TOTAL:,} итераций: {t_seq:.3f} c") t2 = run_threads(2, TOTAL // 2) print(f"2 потока, по {TOTAL // 2:,}: {t2:.3f} c " f"(ускорение x{t_seq / t2:.2f})") t4 = run_threads(4, TOTAL // 4) print(f"4 потока, по {TOTAL // 4:,}: {t4:.3f} c " f"(ускорение x{t_seq / t4:.2f})") print("\nУскорения нет (даже хуже!) — GIL. Но тот же код с time.sleep") print("ускорился бы почти идеально (демо 01). Разницу изучаем в лабе 3.") if __name__ == "__main__": main()