Sobes.tech
Middle+

İş parçaları arasında məlumatların sinxronizasiyası və kontekstin uyğunluğunun təmin edilməsi necə həyata keçirilir?

sobes.tech Süni İntellekt

AI-dan cavab

Məlumatların sinxronizasiyası və çox axınlı tətbiqdə kontekstin uyğunluğunun təmin edilməsi üçün aşağıdakı yanaşmalar istifadə olunur:

  1. NSLock / Lock: Kritikal kod bölmələrini kilidləmək üçün sadə mutexlər.

    import Foundation
    
    class ThreadSafeCounter {
        private var count: Int = 0
        private let lock = NSLock()
    
        func increment() {
            lock.lock()
            defer { lock.unlock() } // Kilidi açmağı təmin edir
            count += 1
        }
    
        func getCount() -> Int {
            lock.lock()
            defer { lock.unlock() }
            return count
        }
    }
    
  2. NSRecursiveLock: Eyni axın içində yenidən kilidləməyə imkan verir.

    import Foundation
    
    class RecursiveLocker {
        private let lock = NSRecursiveLock()
    
        func firstMethod() {
            lock.lock()
            defer { lock.unlock() }
            print("Birinci metod")
            secondMethod() // Yenidən kilidləmək mümkündür
        }
    
        func secondMethod() {
            lock.lock()
            defer { lock.unlock() }
            print("İkinci metod")
        }
    }
    
  3. NSCondition / NSConditionLock: Axınların müəyyən bir şərt (Condition) və ya dəyər (ConditionLock) üçün gözləməsinə imkan verir. Producer-consumer nümunəsinin həyata keçirilməsi üçün istifadə olunur.

    import Foundation
    
    class Buffer {
        private var items: [Int] = []
        private let condition = NSCondition()
        private let capacity = 5
    
        func addItem(_ item: Int) {
            condition.lock()
            defer { condition.unlock() }
    
            while items.count == capacity {
                condition.wait() // Boş yer yaranana qədər gözləyir
            }
    
            items.append(item)
            print("Əlavə edildi: \(item), Cari Buffer: \(items)")
            condition.signal() // Gözləyən axınlara siqnal verir
        }
    
        func removeItem() -> Int {
            condition.lock()
            defer { condition.unlock() }
    
            while items.isEmpty {
                condition.wait() // Elementin yaranmasını gözləyir
            }
    
            let item = items.removeFirst()
            print("Silindi: \(item), Cari Buffer: \(items)")
            condition.signal() // Yer üçün gözləyən axınlara siqnal verir
            return item
        }
    }
    
  4. Grand Central Dispatch (GCD):

    • Serial Queues: Tapşırıqları ardıcıl olaraq, bir dəfəlik icra edir və resurslara atomik giriş təmin edir.

    • Concurrent Queues with Barrier Flags: Oxuma əməliyyatlarını eyni vaxtda icra etməyə imkan verir, lakin yazma əməliyyatları (write) müstəsna şəkildə icra olunur. Bu, oxu-yazı kilid modelini həyata keçirir.

      import Foundation
      
      class ThreadSafeArray<Element> {
          private var array: [Element] = []
          private let queue =
          DispatchQueue(label: "com.mycompany.threadsafearray", attributes: .concurrent) // Eyni vaxtlı queue
      
          func append(_ newElement: Element) {
              queue.async(flags: .barrier) { // Barrier yazma üçün
                  self.array.append(newElement)
              }
          }
      
          func get(at index: Int) -> Element? {
              var result: Element?
              queue.sync { // Oxuma üçün sync (və ya async, əgər oxuma sırası vacib deyilsə)
                  if index < self.array.count {
                      result = self.array[index]
                  }
              }
              return result
          }
      }
      
  5. Core Data Context əməliyyatları: Hər NSManagedObjectContext özəl serial axınına malikdir. Obektlərə və kontekstə giriş yalnız bu axından həyata keçirilməlidir.

    import CoreData
    
    // Core Data kontekstində saxlama nümunəsi
    let context = // Əldə edilmiş kontekst
    context.perform { // Kontekstin özəl axınında icra
        // Core Data obektləri ilə işləmə
        do {
            try context.save()
        } catch {
            // Xəta ilə işləmə
        }
    }
    

Yöntəm seçimi konkret tapşırığa və performans tələblərinə bağlıdır. GCD ilə serial və ya eyni vaxtlı queue-lər və bariyerlər istifadə etmək ən çox tövsiyə olunan yanaşmadır, çünki onlar effektiv və istifadəsi asandır. Core Data üçün isə həmişə perform və ya performAndWait metodlarından istifadə edin.