주기와 마감 시간
100분 안팎
학습 목표
이벤트 시각에서 100ms 주기의 예정 시각과 지연을 계산합니다.
개념
주기와 마감 시간의 계약을 구현합니다
센서 기록기를 반복문 호출 횟수로 구동하면 버튼 검사나 출력이 오래 걸린 순간부터 수집 간격이 달라집니다. 앞 모듈은 버튼이 켜진 호출마다 저장했지만 이번에는 시작 기준 시각에 100ms 간격의 예정선을 그립니다. 호출 시각과 예정 시각을 구분해야 수집 지연을 설명할 수 있습니다. 횟수가 맞아도 늦게 처리했을 수 있으므로 건수만으로 일정 준수를 판정하지 않습니다.
이번 모듈의 브라우저 실습은 Python 3이며 로컬 실습은 C11·make·Python 표준 라이브러리를 사용합니다. 압축 파일을 독립 폴더에 풀고 Makefile 위치에서 make test를 실행합니다. gcc --version으로 실제 컴파일러를 기록합니다. starter의 기능 검사는 일부 실패하고 solution은 통과합니다. 운영 코드나 테스트 기대값을 수정하지 않고 각 events.c의 미완성 동작을 고칩니다.
시간표의 기준은 0ms이고 첫 예정 시각은 100ms입니다. k번째 예정은 100 곱하기 k이며 0ms 자체는 수집 이벤트가 아닙니다. 입력은 첫 줄에 처리 시각 개수 n, 다음 공백 구분 정수 n개를 줍니다. n은 0~1000이며 시각은 감소하지 않고 k번째 처리 시각은 k번째 예정 이상입니다. 이 레슨은 순환 없는 정수 시간표만 계산합니다.
주기는 두 예정 시각 사이의 거리입니다. 지연은 실제 처리 시각에서 그 이벤트의 예정 시각을 뺀 값입니다. 예를 들어 예정 200ms를 235ms에 처리하면 지연은 35ms입니다. 이번 시간표의 허용 지연은 20ms로 정하며 지연 20ms는 OK, 21ms부터 LATE입니다. 이 20ms는 제품 요구를 연습하기 위한 계약이며 모든 센서의 성능 기준이 아닙니다.
마감은 해당 이벤트의 예정 시각에 허용 지연을 더한 시각입니다. 주기 100ms와 허용 지연 20ms는 역할이 다릅니다. 다음 이벤트가 300ms라고 해서 200ms 이벤트를 299ms까지 처리해도 정상이라는 뜻은 아닙니다. 요구사항에 주기만 있고 허용 지연이 없으면 담당자에게 측정 목적과 데이터 신선도 기준을 확인해야 합니다. 이 실습은 그 판단을 명시한 경우입니다.
첫 이벤트를 105ms, 다음을 205ms에 처리하면 지연은 각각 5ms입니다. 앞 처리 시각 105에 100을 더하는 방식은 예정선을 205로 옮겨 첫 지연을 숨깁니다. 실제 완료 시각 기준의 지연 반복이 필요한 작업도 있지만 고정 기준 센서 일정과는 계약이 다릅니다. 구현 전에 고정 주기인지 완료 후 대기인지 문서에 적고 테스트 기대값도 그 정책에 맞춥니다.
최대 지연은 개별 지연의 최댓값이고 늦은 건수는 LATE로 판정된 이벤트 수입니다. 평균만 보면 한 번 크게 늦은 이벤트가 다수의 정상 이벤트에 묻힐 수 있습니다. 이번 출력은 이벤트마다 예정·처리·지연·상태를 남기고 마지막에 MAX와 LATE를 요약합니다. 건수가 0이면 MAX 0 LATE 0입니다. 빈 관찰을 모든 상황에서 일정이 맞았다는 증거로 해석하지 않습니다.
브라우저 채점은 출력 토큰을 비교하므로 소수점 값을 만들 이유가 없습니다. 모든 시간 단위는 정수 ms입니다. 100.0 대신 100을 출력하고 상태는 대문자 OK 또는 LATE로 적습니다. Python의 enumerate에서 시작 인덱스를 1로 지정하면 첫 예정이 100이 됩니다. 기본 0을 그대로 곱하면 첫 예정이 0으로 계산되어 모든 지연이 100ms 크게 보입니다.
따라하기에서는 실제 센서나 sleep을 쓰지 않습니다. 시각 목록이 이미 관찰 로그이고 계산기는 그 로그를 분석합니다. PC가 빠르게 실행된다고 지연이 0인 것이 아니며 느리게 실행된다고 로그의 지연이 증가하지도 않습니다. 프로그램 실행 시간과 입력에 기록된 가상 시간을 따로 읽습니다. 결과가 같아야 하는 결정적 검사는 시간 관련 버그를 작은 입력으로 재현하는 데 도움이 됩니다.
실제 처리 간격과 예정 지연도 나누어 봅니다. 처리 시각 100·230·300이면 실제 간격은 130·70ms이지만 예정 지연은 0·30·0ms입니다. 간격이 짧아졌다고 데이터가 항상 더 신선해지는 것은 아닙니다. 앞 이벤트가 늦어서 다음 이벤트와 가까워진 것일 수 있습니다. 이 시간표에서는 이벤트 번호가 주어지는 순서와 일치한다고 가정하며 누락 번호를 추정하지 않습니다.
입력 개수와 시각 개수가 맞지 않으면 분석을 시작하지 않습니다. 실습 계약은 올바른 입력을 채점하지만 로컬 로그를 읽을 때는 n과 실제 길이를 먼저 비교합니다. ValueError는 정수 변환 대상에 다른 문자가 섞인 경우를 가리키고 IndexError는 길이 계약을 놓친 접근을 의심할 근거입니다. 숫자가 여러 줄로 나뉘어도 split은 공백을 처리하므로 줄 배치에 의존하지 않습니다.
음수 지연이 나왔다면 처리 시각이 예정보다 앞섰거나 이벤트 번호가 어긋났는지 확인합니다. abs로 음수를 양수로 바꾸면 데이터 계약 위반을 숨깁니다. 100ms 이벤트가 누락되어 다음 200ms 로그를 첫 항목으로 넣으면 분석 결과가 달라집니다. 실제 수집 로그에는 이벤트 번호 또는 예정 시각을 함께 남겨 재구성할 수 있어야 합니다. 이 레슨은 순번 누락 없는 입력으로 범위를 제한합니다.
허용 지연의 경계는 작은 테스트로 확인합니다. 120ms는 100ms 예정에서 20ms 늦어 OK이고 121ms는 LATE입니다. 최대 지연 0과 입력 0개를 따로 시험하면 초기값 오류를 잡습니다. 늦은 이벤트가 마지막에만 있는 입력은 루프 안에서 계수를 갱신하는지 확인합니다. 동일한 처리 시각도 서로 다른 예정 이벤트일 수 있으므로 임의로 중복 제거하지 않습니다.
실습을 마치면 예정 계산 식, 허용 지연 비교 식, 요약 누적 위치를 손으로 설명합니다. 단순히 정답 문자열을 외우는 대신 첫 순번을 바꾸었을 때 어떤 행부터 틀리는지 예측합니다. 이후 C 타이머는 이 예정선을 생성하고 큐는 처리까지의 간격을 드러냅니다. 하드웨어 타이머 분주와 레지스터 계산은 더 읽기에서 보충하고 여기서는 기록기의 일정 계약과 관찰에 집중합니다.
따라하기
예정과 실제 비교
브라우저 Python 실행기에 입력하고 정수 ms 기준으로 결과를 확인합니다.
for k, actual in enumerate([105, 235, 300], 1):
print(k * 100, actual, actual - k * 100)실행 결과
100 105 5 200 235 35 300 300 0
허용 경계 판정
브라우저 Python 실행기에 입력하고 정수 ms 기준으로 결과를 확인합니다.
for delay in [0, 20, 21]:
print(delay, "LATE" if delay > 20 else "OK")실행 결과
0 OK 20 OK 21 LATE
요약 계산
브라우저 Python 실행기에 입력하고 정수 ms 기준으로 결과를 확인합니다.
delays = [5, 35, 0]
print("MAX", max(delays), "LATE", sum(d > 20 for d in delays))실행 결과
MAX 35 LATE 1
확인 문제
실습
첫 줄 n과 다음 n개 처리 시각을 읽습니다. k번째 예정은 100*k, 지연은 처리-예정입니다. 허용 지연 20ms를 넘을 때만 LATE입니다. 각 행에 예정 처리 지연 상태를 공백으로 출력하고 마지막에 MAX 최대지연 LATE 늦은건수를 출력합니다. n=0이면 MAX 0 LATE 0입니다. 시각은 비감소, 처리 시각은 해당 예정 이상이며 누락 번호는 없습니다.
모범 답안
import sys
values = list(map(int, sys.stdin.read().split()))
n = values[0]
maximum = late = 0
for k, actual in enumerate(values[1:1+n], 1):
due = k * 100
delay = actual - due
status = "LATE" if delay > 20 else "OK"
maximum = max(maximum, delay)
late += status == "LATE"
print(due, actual, delay, status)
print("MAX", maximum, "LATE", late)
더 읽기
면접 질문
- 타이머 이벤트가 밀렸을 때 예정 시각과 실제 수집 시각을 어떻게 구분하나요?
- 고정 주기 작업과 완료 후 대기 작업의 차이를 설명해 주세요.