Sobes.tech
Middle

Czym jest semafor w kontekście programowania?

sobes.tech AI

Odpowiedź od AI

Semafor to prymityw synchronizacji wątków, który kontroluje dostęp do ograniczonego zasobu. Utrzymuje licznik całkowity.

Podstawowe operacje:

  • wait() (lub P / acquire) : Zmniejsza licznik o 1. Jeśli licznik stanie się ujemny, wątek zostanie zablokowany do czasu wykonania signal() przez inny wątek.
  • signal() (lub V / release) : Zwiększa licznik o 1. Jeśli są zablokowane wątki, jeden z nich zostanie odblokowany.

Typy semaforów:

  • Semafor binarny (mutex) : Licznik przyjmuje wartości 0 lub 1. Używany do zapewnienia wzajemnego wykluczania – tylko jeden wątek może uzyskać dostęp do zasobu jednocześnie.
  • Semafor liczbowy : Licznik może przyjmować wartości od 0 do N. Używany do zarządzania dostępem do puli zasobów z ograniczoną liczbą dostępnych elementów.

Przykład użycia w Swift do ograniczenia liczby jednoczesnych zadań:

// Tworzenie semafora pozwalającego na maksymalnie 3 równoczesne dostęp
let semaphore = DispatchSemaphore(value: 3)

DispatchQueue.global().async {
    // Zadanie 1
    semaphore.wait() // Zmniejsza licznik, blokuje jeśli > 3 zadania są w toku
    print("Zadanie 1 rozpoczęte")
    Thread.sleep(forTimeInterval: 2) // Symulacja pracy
    print("Zadanie 1 zakończone")
    semaphore.signal() // Zwiększa licznik, odblokowuje oczekujące zadania
}

DispatchQueue.global().async {
    // Zadanie 2
    semaphore.wait()
    print("Zadanie 2 rozpoczęte")
    Thread.sleep(forTimeInterval: 3)
    print("Zadanie 2 zakończone")
    semaphore.signal()
}

DispatchQueue.global().async {
    // Zadanie 3
    semaphore.wait()
    print("Zadanie 3 rozpoczęte")
    Thread.sleep(forTimeInterval: 1)
    print("Zadanie 3 zakończone")
    semaphore.signal()
}

DispatchQueue.global().async {
    // Zadanie 4 (będzie czekać, aż zwolni się miejsce)
    semaphore.wait()
    print("Zadanie 4 rozpoczęte")
    Thread.sleep(forTimeInterval: 2)
    print("Zadanie 4 zakończone")
    semaphore.signal()
}

// Czekanie na zakończenie wszystkich zadań dla demonstracji
// W rzeczywistym kodzie używaj bardziej niezawodnych mechanizmów oczekiwania
Thread.sleep(forTimeInterval: 5)