Как "работает" псевдокод реализации Wait/Signal (семафор)?
Wait(semaphore sem) {
DISABLE_INTS
sem.val--
if (sem.val < 0){
add thread to sem.L
block(thread)
}
ENABLE_INTS
Signal(semaphore sem){
DISABLE_INTS
sem.val++
if (sem.val <= 0) {
th = remove next
thread from sem.L
wakeup(th)
}
ENABLE_INTS
Если block(thread)
останавливает thread
от выполнения, как, где и когда он возвращается?
Какой поток разрешает прерывания после Wait()
? thread
это называется block()
не должен возвращаться, пока другой поток не вызвал wakeup(thread)
!
- но как запустить этот другой поток?
- где именно происходит переключение потока?
2 ответа
block(thread)
работает так:
- Включает прерывания
- Использует некоторый механизм ожидания (предоставляемый операционной системой или ожидание занятости в простейшем случае) для ожидания до
wakeup(thread)
по этой теме называется. Это означает, что в этой точкеthread
уступает свое время планировщику. - Отключает прерывания и возвращает.
Да, UP и DOWN в основном полезны при вызове из разных потоков, но не исключено, что вы вызываете их с одним потоком - если вы запускаете семафор со значением> 0, то один и тот же поток может войти в критическую секцию и выполнить оба DOWN (до) и UP (после). Значение, которое инициализирует семафор, указывает, сколько потоков может одновременно войти в критическую секцию, которая может быть 1 (мьютекс) или любым другим положительным числом.
Как создаются темы? Это не показано на слайде лекции, потому что это только принцип работы семафора с использованием псевдокода. Но это совсем другая история о том, как вы используете эти семафоры в своем приложении.