공정 분배와 UNIX 스케줄링 문서의 검증 코드다. if __name__ == "__main__": 아래가 자체 테스트다.
"""전통 UNIX 스케줄링(그림 9.17)과 공정 분배 스케줄러(그림 9.16)의 우선순위 계산을 재현한다.
매 초 끝에: CPU = CPU/2, 우선순위 = 기본 + CPU/2 (+ 그룹 CPU/(4W)). 나눗셈은 항마다 소수점을 버린다. 값이 작을수록 우선순위가 높다.
한 초 동안 실행된 프로세스는 CPU 카운트가 60 늘어난다. 동률이면 앞 프로세스(A, B, C 순)."""
def unix(seconds=5, base=60):
cpu = {p: 0 for p in "ABC"}
prio = {p: base for p in "ABC"}
rows = []
for _ in range(seconds):
run = min("ABC", key=lambda p: (prio[p], "ABC".index(p)))
rows.append((run, dict(prio)))
cpu[run] += 60
for p in "ABC":
cpu[p] //= 2
prio[p] = base + cpu[p] // 2
rows.append((None, dict(prio)))
return rows
def fair(seconds=5, base=60, W=0.5):
group = {"A": 1, "B": 2, "C": 2}
cpu = {p: 0 for p in "ABC"}; gcpu = {1: 0, 2: 0}
prio = {p: base for p in "ABC"}
rows = []
for _ in range(seconds):
run = min("ABC", key=lambda p: (prio[p], "ABC".index(p)))
rows.append((run, dict(prio)))
cpu[run] += 60; gcpu[group[run]] += 60
for p in "ABC":
cpu[p] //= 2
for g in gcpu:
gcpu[g] //= 2
for p in "ABC":
prio[p] = base + int(cpu[p] / 2) + int(gcpu[group[p]] / (4 * W)) # 항마다 소수점 버림 (그림 9.16과 같음)
rows.append((None, dict(prio)))
return rows
if __name__ == "__main__":
u = unix()
print(u)
assert [r[0] for r in u[:5]] == ["A", "B", "C", "A", "B"]
assert [r[1]["A"] for r in u] == [60, 75, 67, 63, 76, 68]
assert [r[1]["C"] for r in u] == [60, 60, 60, 75, 67, 63]
f = fair()
print(f)
assert [r[0] for r in f[:5]] == ["A", "B", "A", "C", "A"]
assert [r[1]["A"] for r in f] == [60, 90, 74, 96, 78, 98]
assert [r[1]["B"] for r in f] == [60, 60, 90, 74, 81, 70]
assert [r[1]["C"] for r in f] == [60, 60, 75, 67, 93, 76]
assert 60 + (80 // 2) // 2 == 80 # 카드 C1
print("ALL CHECKS PASSED")