Init
This commit is contained in:
commit
c394677d07
59 files changed
+5149
No files matched your search
@@ -0,0 +1,76 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Демо: GIL изнутри — интервал переключения и stat.
|
||||
|
||||
Запуск из корня курса:
|
||||
python lab03_gil/examples/01_gil_basics_demo.py
|
||||
|
||||
Показывает:
|
||||
- sys.getswitchinterval() — как часто потоки уступают GIL;
|
||||
- sys._is_gil_enabled() (Python 3.13+) — статус GIL;
|
||||
- поток-«наблюдатель» работает, пока главный поток занят счётом
|
||||
(переключения есть!), но суммарная производительность не растёт.
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
|
||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")))
|
||||
|
||||
|
||||
def burn(n):
|
||||
s = 0.0
|
||||
for i in range(n):
|
||||
s += i ** 0.5
|
||||
return s
|
||||
|
||||
|
||||
def main():
|
||||
print(f"Python: {sys.version.split()[0]}")
|
||||
if hasattr(sys, "_is_gil_enabled"):
|
||||
print(f"GIL включён: {sys._is_gil_enabled()}")
|
||||
print(f"интервал переключения GIL: {sys.getswitchinterval() * 1000:.0f} мс\n")
|
||||
|
||||
N = 4_000_000
|
||||
|
||||
# 1. Один поток
|
||||
t0 = time.perf_counter()
|
||||
burn(N)
|
||||
t1 = time.perf_counter() - t0
|
||||
print(f"1 поток: {t1:.3f} c")
|
||||
|
||||
# 2. Поток-наблюдатель: он живёт (переключения идут), но работе это не помогает
|
||||
ticks = [0]
|
||||
|
||||
def observer(stop_flag):
|
||||
while not stop_flag[0]:
|
||||
ticks[0] += 1
|
||||
time.sleep(0.005)
|
||||
|
||||
stop = [False]
|
||||
obs = threading.Thread(target=observer, args=(stop,), daemon=True)
|
||||
obs.start()
|
||||
|
||||
t0 = time.perf_counter()
|
||||
burn(N) # главный поток считает
|
||||
t2 = time.perf_counter() - t0
|
||||
stop[0] = True
|
||||
obs.join()
|
||||
print(f"1 поток + наблюдатель: {t2:.3f} c (наблюдатель проснулся "
|
||||
f"{ticks[0]} раз) — работа не замедлилась: переключения дешёвые")
|
||||
|
||||
# 3. Два считающих потока: время то же, работы вдвое больше — но не быстрее
|
||||
t0 = time.perf_counter()
|
||||
threads = [threading.Thread(target=burn, args=(N // 2,)) for _ in range(2)]
|
||||
for t in threads:
|
||||
t.start()
|
||||
for t in threads:
|
||||
t.join()
|
||||
t4 = time.perf_counter() - t0
|
||||
print(f"2 потока по {N // 2}: {t4:.3f} c => S={t1 / t4:.2f} (GIL!)")
|
||||
print("\nВывод: переключения GIL происходят, но байт-код всё равно")
|
||||
print("исполняется по очереди — суммарная скорость не растёт.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in new issue
Block a user