Sobes.tech
Middle

Какво е семафор в контекста на програмирането?

sobes.tech AI

Отговор от AI

Семафорът е примитив за синхронизация на нишки, който управлява достъпа до ограничен ресурс. Той поддържа цяло число-бройчик.

Основни операции:

  • wait() (или P / acquire) : Намалява брояча с 1. Ако броячът стане отрицателен, нишката се блокира, докато друга нишка изпълни signal().
  • signal() (или V / release) : Увеличава брояча с 1. Ако има блокирани нишки, една от тях се отключва.

Типове семафори:

  • Бинарен семафор (mutex) : Броячът приема стойности 0 или 1. Използва се за осигуряване на взаимно изключване – само една нишка може да получи достъп до ресурса едновременно.
  • Броящ семафор : Броячът може да приема стойности от 0 до N. Използва се за управление на достъпа до пул от ресурси с ограничен брой налични елементи.

Пример за използване в Swift за ограничаване на броя на задачите, които могат да се изпълняват едновременно:

// Създаване на семафор, който позволява до 3 едновременни достъпа
let semaphore = DispatchSemaphore(value: 3)

DispatchQueue.global().async {
    // Задача 1
    semaphore.wait() // Намалява брояча, блокира ако > 3 задачи работят
    print("Задача 1 стартира")
    Thread.sleep(forTimeInterval: 2) // Симулация на работа
    print("Задача 1 завърши")
    semaphore.signal() // Увеличава брояча, отключва чакащите задачи
}

DispatchQueue.global().async {
    // Задача 2
    semaphore.wait()
    print("Задача 2 стартира")
    Thread.sleep(forTimeInterval: 3)
    print("Задача 2 завърши")
    semaphore.signal()
}

DispatchQueue.global().async {
    // Задача 3
    semaphore.wait()
    print("Задача 3 стартира")
    Thread.sleep(forTimeInterval: 1)
    print("Задача 3 завърши")
    semaphore.signal()
}

DispatchQueue.global().async {
    // Задача 4 (ще чака, докато не се освободи място)
    semaphore.wait()
    print("Задача 4 стартира")
    Thread.sleep(forTimeInterval: 2)
    print("Задача 4 завърши")
    semaphore.signal()
}

// Изчакване всички задачи да приключат за демонстрация
// В реален код използвайте по-надеждни механизми за изчакване
Thread.sleep(forTimeInterval: 5)