# -*- coding: utf-8 -*- """Демо: Semaphore — лимит одновременного доступа к ресурсу. Запуск из корня курса: python lab05_sync/examples/02_semaphore_demo.py Имитация: 10 «клиентов», ресурс допускает 3 одновременных подключения. Семафор гарантирует: активных клиентов никогда не больше 3. """ import os import sys import threading import time sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))) MAX_CONN = 3 N_CLIENTS = 10 DELAY = 0.2 active = 0 active_lock = threading.Lock() max_seen = [0] def client(idx, sem): global active with sem: # ждём свободный «слот» with active_lock: active += 1 max_seen[0] = max(max_seen[0], active) print(f" клиент {idx:>2} подключился (активно: {active})") time.sleep(DELAY) # «работа с ресурсом» with active_lock: active -= 1 print(f" клиент {idx:>2} отключился (активно: {active})") def main(): sem = threading.Semaphore(MAX_CONN) threads = [threading.Thread(target=client, args=(i, sem)) for i in range(N_CLIENTS)] t0 = time.perf_counter() for t in threads: t.start() for t in threads: t.join() total = time.perf_counter() - t0 print(f"\nмаксимум одновременно: {max_seen[0]} (лимит {MAX_CONN})") print(f"время: {total:.2f} c, идеал ≈ {N_CLIENTS / MAX_CONN * DELAY:.2f} c") print("Если max_seen > лимита — семафор сломан (такого быть не должно).") if __name__ == "__main__": main()