질문에 답하기 위해서는 세마포어의 기본적인 작동 원리와 sema_down 및 sema_up 함수에서의 역할에 대해 이해해야 합니다. 세마포어는 공유 자원에 대한 접근을 동기화하는 매커니즘으로, 특정 자원을 사용하려는 스레드들 사이에서 경쟁 상태를 방지합니다.
sema_down 함수 (P = wait = lock = down)
sema_down은 세마포어의 값을 감소시키는 연산으로, 세마포어의 값이 0이 되면 해당 함수를 호출한 스레드를 대기 상태로 전환합니다. 이 함수는 다음과 같은 과정을 따릅니다:
- 인터럽트 비활성화: 세마포어 연산 도중에 인터럽트가 발생하지 않도록 하여 원자적(atomic) 연산을 보장합니다.
- 값 확인 및 대기: 세마포어의 값이 0이면, 현재 스레드는 세마포어의 대기열(waiters)에 추가되고, 스레드는 대기 상태로 전환됩니다(thread_block()). 이 때 스레드는 세마포어가 다시 사용 가능해질 때까지 실행을 중지합니다.
- 세마포어 감소: 세마포어 값이 0보다 크면, 값을 감소시키고 스레드는 계속 실행됩니다.
sema_up 함수 (V = signal = unlock = up)
sema_up은 세마포어의 값을 증가시키는 연산으로, 대기열에 있는 스레드가 있다면 하나를 깨워 실행 상태로 전환합니다. 이 함수는 다음과 같은 과정을 따릅니다:
- 인터럽트 비활성화: 마찬가지로, 연산 중 인터럽트를 비활성화하여 원자성을 유지합니다.
- 대기 스레드 깨우기: 대기열에서 스레드를 하나 꺼내 (list_pop_front) 실행 상태로 전환합니다(thread_unblock). 이는 세마포어가 사용 가능해졌음을 의미하며, 꺼내진 스레드는 이제 자원을 사용할 수 있습니다.
- 세마포어 증가: 세마포어의 값을 증가시킵니다.
왜 sema_up에서 스레드를 깨우나?
sema_down에서 스레드를 대기 상태로 전환하는 이유는 자원(세마포어)이 사용 불가능하기 때문입니다. 반면, sema_up에서 스레드를 깨우는 이유는 자원이 다시 사용 가능해졌기 때문입니다. 만약 sema_down에서 스레드를 깨우려고 한다면, 자원이 여전히 사용 중일 때 스레드가 실행을 시도할 수 있으므로 동기화 문제가 발생할 수 있습니다.
따라서, sema_down에서는 자원을 안전하게 대기할 수 있도록 스레드를 대기 상태로 만들고, sema_up에서는 자원이 사용 가능해짐에 따라 대기 중인 스레드 중 하나를 깨워 실행할 수 있도록 합니다. 이렇게 함으로써 자원의 동기화와 스레드 스케줄링을 효과적으로 관리할 수 있습니다.

check point
sema_down일 때 wait list에 삽입이 제대로 되고 있는지 확인
sema_up일 때 unblock이 제대로 실행되는 지 확인
priority-sema가 안 되던 이유
sema_up에서 preempt_priority(ready_list의 priority가 현재 스레드의 priority보다 높으면 양보하는 함수)를 안 해서 그랬다.
힘이 쭉 빠진다.. 충분히 생각해낼 수 있는 문제였는데.
'크래프톤 정글 일지' 카테고리의 다른 글
[PintOS] User Programs 개요 (0) | 2024.05.20 |
---|---|
[PintOS] GDB 사용법 (0) | 2024.05.16 |
장병규 의장님과 티타임 (0) | 2024.05.16 |
[PintOS] alarm-clock 함수들 (0) | 2024.05.15 |
github default branch 변경 (0) | 2024.05.15 |