Как "работает" псевдокод реализации 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) работает так:

  1. Включает прерывания
  2. Использует некоторый механизм ожидания (предоставляемый операционной системой или ожидание занятости в простейшем случае) для ожидания до wakeup(thread) по этой теме называется. Это означает, что в этой точке thread уступает свое время планировщику.
  3. Отключает прерывания и возвращает.

Да, UP и DOWN в основном полезны при вызове из разных потоков, но не исключено, что вы вызываете их с одним потоком - если вы запускаете семафор со значением> 0, то один и тот же поток может войти в критическую секцию и выполнить оба DOWN (до) и UP (после). Значение, которое инициализирует семафор, указывает, сколько потоков может одновременно войти в критическую секцию, которая может быть 1 (мьютекс) или любым другим положительным числом.

Как создаются темы? Это не показано на слайде лекции, потому что это только принцип работы семафора с использованием псевдокода. Но это совсем другая история о том, как вы используете эти семафоры в своем приложении.

Другие вопросы по тегам