Sobes.tech
Middle

Программалоо контекстинде семафор деген эмне?

sobes.tech AI

AIден жооп

Семафор — бул потокторду синхрондоштуруу прими-тиви, ал чектелген ресурска кирүүнү башкаруу үчүн колдонулат. Ал бүтүн сандык эсептегичти колдойт:

Негизги операциялар:

  • wait() (же P / acquire): эсептегичти 1ге азайтат. Эсептегич терс болуп калса, поток блоктолот, башка поток signal() аткарышына чейин.
  • signal() (же V / release): эсептегичти 1ге көбөйтөт. Блоктолгон потоктор бар болсо, алардын бири бошотулат.

Семафордун түрлөрү:

  • Бинардык семафор (мьютекс): эсептегич 0 же 1 маанилерди кабыл алат. Бир мезгилде бир гана поток ресурска кирүүгө мүмкүндүк берет — өз ара исключение камсыз кылуу үчүн.
  • Эсептөө семафору: эсептегич 0ден Nге чейин маанилерди кабыл алат. Чектелген ресурстардын пулуна кирүүнү башкаруу үчүн колдонулат.

Swiftте колдонуу мисалы — бир убакта иштеген тапшырмалардын санын чектөө үчүн:

// 3кө чейин бир убакта иштей турган семафор түзүү
let semaphore = DispatchSemaphore(value: 3)

DispatchQueue.global().async {
    // Биринчи тапшырма
    semaphore.wait() // эсептегичти азайтат, 3төн көп болсо күтөт
    print("Тапшырма 1 башталды")
    Thread.sleep(forTimeInterval: 2) // ишти имитациялоо
    print("Тапшырма 1 аяктады")
    semaphore.signal() // эсептегичти көбөйтөт, күтүп жаткан тапшырмаларды бошотот
}

DispatchQueue.global().async {
    // Экинчи тапшырма
    semaphore.wait()
    print("Тапшырма 2 башталды")
    Thread.sleep(forTimeInterval: 3)
    print("Тапшырма 2 аяктады")
    semaphore.signal()
}

DispatchQueue.global().async {
    // Үчүнчү тапшырма
    semaphore.wait()
    print("Тапшырма 3 башталды")
    Thread.sleep(forTimeInterval: 1)
    print("Тапшырма 3 аяктады")
    semaphore.signal()
}

DispatchQueue.global().async {
    // Төртүнчү тапшырма (күтөт, слот бошотулгуча)
    semaphore.wait()
    print("Тапшырма 4 башталды")
    Thread.sleep(forTimeInterval: 2)
    print("Тапшырма 4 аяктады")
    semaphore.signal()
}

// Бардык тапшырмалар бүтөрүн күтүп, көрсөтүү үчүн
// Реалдуу коддо ишенимдүү күтүү механизмдерин колдонуңуз
Thread.sleep(forTimeInterval: 5)