Sobes.tech
Back to questions
Senior
122
questionbank

Что такое инверсия приоритетов?

Sobes Copilot

Get answers in real time

Answer from AI

sobes.tech AI

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

Пример сценария:

  1. Задача H (высокий приоритет) пытается получить доступ к ресурсу R и блокируется, так как R занят.
  2. Задача L (низкий приоритет) удерживает ресурс R.
  3. Задача M (средний приоритет) становится готовой к выполнению и вытесняет L.
  4. Таким образом, H, несмотря на высокий приоритет, вынуждена ждать, пока M завершится, а затем L возобновится и освободит R.

Решения:

  • Протокол наследования приоритетов (Priority Inheritance Protocol): Задача, которая удерживает ресурс, необходимый задаче с более высоким приоритетом, временно наследует приоритет этой высокоприоритетной задачи на время удержания ресурса.
  • Протокол ограничения приоритетов (Priority Ceiling Protocol): Каждому ресурсу присваивается потолок приоритета, равный наивысшему приоритету задачи, которая может использовать этот ресурс. Задача может получить доступ к ресурсу только если её приоритет выше потолка приоритета любого ресурса, занятого другими задачами, или если она сама уже удерживает этот ресурс.
// Пример упрощенной демонстрации без использования реальных механизмов планирования
import Foundation

let resource = NSCondition()
var resourceInUse = false

func lowPriorityTask() {
    print("Low Priority: Trying to acquire resource...")
    resource.lock()
    while resourceInUse {
        resource.wait()
    }
    resourceInUse = true
    print("Low Priority: Acquired resource.")

    // Имитация работы
    Thread.sleep(forTimeInterval: 2)

    resourceInUse = false
    print("Low Priority: Released resource.")
    resource.signal()
    resource.unlock()
}

func mediumPriorityTask() {
    print("Medium Priority: Running...")
    // Имитация работы, которая может вытеснить низкоприоритетную задачу
    Thread.sleep(forTimeInterval: 3)
    print("Medium Priority: Finished.")
}

func highPriorityTask() {
    print("High Priority: Trying to acquire resource...")
    resource.lock()
    while resourceInUse {
        print("High Priority: Waiting for resource...")
        resource.wait()
    }
    resourceInUse = true
    print("High Priority: Acquired resource.")

    // Имитация работы
    Thread.sleep(forTimeInterval: 1)

    resourceInUse = false
    print("High Priority: Released resource.")
    resource.signal()
    resource.unlock()
}

let lowQ = DispatchQueue(label: "com.example.low", qos: .utility) // Низкий приоритет
let mediumQ = DispatchQueue(label: "com.example.medium", qos: .userInitiated) // Средний приоритет
let highQ = DispatchQueue(label: "com.example.high", qos: .userInteractive) // Высокий приоритет

// Запускаем задачи в порядке, который может привести к инверсии (сначала низкая, потом высокая, потом средняя)
lowQ.async { lowPriorityTask() }
Thread.sleep(forTimeInterval: 0.1) // Даем низкой задаче шанс начать
highQ.async { highPriorityTask() }
Thread.sleep(forTimeInterval: 0.2) // Даем высокой задаче шанс заблокироваться
mediumQ.async { mediumPriorityTask() }

// В реальной ОС планировщик управляет приоритетами,
// здесь это лишь демонстрация принципа блокировки/ожидания.

RunLoop.main.run(until: Date(timeIntervalSinceNow: 7))