რა არის სემაფორი და მუტექსი?
sobes.tech AI
პასუხი AI-სგან
სემაფორი არის ზოგადი სინქრონიზაციის მექანიზმი, რომელიც გამოიყენება შეზღუდული რესურსის წვდომის მართვაში რამდენიმე კონკურენტული ნაკადის შორის. იგი ინახავს მთელ მნიშვნელობას, რომელიც მცირდება რესურსის დაკავებისას და იზრდება მისი გათავისუფლებისას. თუ სემაფორის მნიშვნელობა არის ნული, მცდელობა მისი დაკავების ბლოკავს ნაკადს, სანამ სხვა ნაკადი არ გაათავისუფლებს რესურსს. შეიძლება გამოყენებულ იქნას ერთდროულად მუშაობა მიმდინარე ნაკადების რაოდენობის შეზღუდვისთვის.
მიუტექსი (mutual exclusion — ურთიერთგამორიცხვა) არის ბინარული სემაფორი, რომელიც შეიძლება იყოს ან დაბლოკილი, ან განბლოკილი. გამოიყენება კრიტიკული სექციის დაცვაში ერთდროულად რამდენიმე ნაკადის წვდომისგან. მხოლოდ ერთი ნაკადი შეუძლია მიუტექსის დაკავება ნებისმიერ დროს. ის, ვინც მიუტექსი დაიკავა, ვერ იქნება შეწყდა სხვა ნაკადის მიერ, რომელიც ცდილობს მის დაკავებას. თუ სცადეთ დაბლოკილი მიუტექსის დაკავება, ნაკადი ბლოკირდება მის გათავისუფლებამდე.
ძირითადი განსხვავებები:
| მახასიათებელი | სემაფორი | მიუტექსი |
|---|---|---|
| ტიპი | ზოგადი სინქრონიზაციის მექანიზმი | ბინარული სემაფორი (სემაფორის სპეციალური შემთხვევა) |
| მნიშვნელობა | მთელი რიცხვი (>= 0) | ბინარული (0 ან 1) |
| დანიშნულება | რესურსებზე წვდომის მართვა, შეზღუდვა | კრიტიკული სექციების დაცვა, ურთიერთგამორიცხვა |
| მფლობელი | შეიძლება არ ჰქონდეს მფლობელი | ყოველთვის აქვს მფლობელი (ნაკადი, რომელმაც დაიკავა) |
| გამოყენება iOS-ზე | DispatchSemaphore |
ხშირად რეალიზებულია DispatchQueue.sync ან NSRecursiveLock-ის საშუალებით |
მიუტექსის გამოყენების მაგალითი კრიტიკული სექციის დაცვისთვის:
// GCD (Grand Central Dispatch) კონტექსტში
let serialQueue = DispatchQueue(label: "com.example.criticalSection")
serialQueue.sync {
// კრიტიკული სექციის კოდი
// მხოლოდ ერთი ნაკადი შეიძლება იყოს აქ ნებისმიერ დროს
}
სემაფორის გამოყენების მაგალითი პარალელური დავალებების შეზღუდვისთვის:
// GCD (Grand Central Dispatch) კონტექსტში
let semaphore = DispatchSemaphore(value: 3) // ნებადართულია 3 პარალელური დავალება
DispatchQueue.global().async {
semaphore.wait() // ამცირებს სემაფორის მნიშვნელობას 1-ით. ბლოკავს, თუ მნიშვნელობა 0-ია.
// დავალების კოდი, რომელიც პარალელურად ხორციელდება
print("დავალება ხორციელდება")
Thread.sleep(forTimeInterval: 1) // სამუშაოს იმიტაცია
semaphore.signal() // ზრდის სემაფორის მნიშვნელობას 1-ით. გამოშვება მოლოდინში მყოფ ნაკადს, თუ არსებობს.
print("დავალება დასრულდა")
}
// შეიძლება განახორციელოთ რამდენიმე ასეთი ბლოკი. მხოლოდ 3 ერთდროულად შესრულდება.