Sobes.tech
Middle

Kas ir semafors programmēšanas kontekstā?

sobes.tech AI

Atbilde no AI

Semafors ir sinhronizācijas primitīvs, kas pārvalda pavedienu piekļuvi ierobežotam resursam. Tas uztur veselu skaitli.

Galvenās operācijas:

  • wait() (vai P / acquire): samazina skaitītāju par 1. Ja skaitītājs kļūst negatīvs, pavediens tiek bloķēts līdz brīdim, kad cits pavediens izpildīs signal().
  • signal() (vai V / release): palielina skaitītāju par 1. Ja ir bloķēti pavedieni, viens no tiem tiek atbloķēts.

Semaforu tipi:

  • Binarā semafors (mutex): skaitītājs pieņem vērtības 0 vai 1. To izmanto savstarpējai izslēgšanai — tikai viens pavediens var piekļūt resursam vienlaikus.
  • Skaitļu semafors: skaitītājs var pieņemt vērtības no 0 līdz N. To izmanto ierobežota resursu pulka piekļuves pārvaldībai.

Piemērs Swift valodā, ierobežojot vienlaicīgi strādājošo uzdevumu skaitu:

// Semafora izveide, kas ļauj līdz 3 vienlaicīgiem piekļuves gadījumiem
let semaphore = DispatchSemaphore(value: 3)

DispatchQueue.global().async {
    // Uzdevums 1
    semaphore.wait() // samazina skaitītāju, bloķē, ja > 3 uzdevumi darbojas
    print("Uzdevums 1 sācies")
    Thread.sleep(forTimeInterval: 2) // darba imitācija
    print("Uzdevums 1 pabeigts")
    semaphore.signal() // palielina skaitītāju, atbloķē gaidošos uzdevumus
}

DispatchQueue.global().async {
    // Uzdevums 2
    semaphore.wait()
    print("Uzdevums 2 sācies")
    Thread.sleep(forTimeInterval: 3)
    print("Uzdevums 2 pabeigts")
    semaphore.signal()
}

DispatchQueue.global().async {
    // Uzdevums 3
    semaphore.wait()
    print("Uzdevums 3 sācies")
    Thread.sleep(forTimeInterval: 1)
    print("Uzdevums 3 pabeigts")
    semaphore.signal()
}

DispatchQueue.global().async {
    // Uzdevums 4 (gaida, kamēr atbrīvos slotu)
    semaphore.wait()
    print("Uzdevums 4 sācies")
    Thread.sleep(forTimeInterval: 2)
    print("Uzdevums 4 pabeigts")
    semaphore.signal()
}

// Gaidām visu uzdevumu pabeigšanu — demonstrācijai
// Izmantojiet uzticamākus gaidīšanas mehānismus
Thread.sleep(forTimeInterval: 5)