İçeriğe geç

DispatchGroup vs DispatchSemaphore kullanımı

Merhabalar bu yazımda Multi Thread işlemlerinde karşılaştığımız DispatchGroup ve DispatchSemaphore yapılarının kullanımını göreceğiz.

Duruma göre işlem bekletme ve ardı ardına beklemeli bir şekilde gerçekleştirilecek işlemler için kullanmamız gereken yapılardır. Semaphore yapısı ve Group yapısı bir birlerine oldukça benzer yapılardır.

Aşağıda yazdığım örnekleri inceleyelim.

Bu işlemleri göstermek için basit bir servis istek fonksiyonu yazdım.

func fetchData(completion: @escaping (_ val:Data) -> Void) {
        guard let url = URL(string: "https://httpbin.org/get") else { return }
        URLSession.shared.dataTask(with: url) { (data, response, error) in
            guard error == nil else { return }
            completion(data ?? Data())
        }.resume()
    }

İlk olarak DispatchGroup kullanımını görelim.

let group = DispatchGroup()

        group.enter()
        fetchData { (data) in
            print("Fetch Data - 1 @",data)
            group.leave()
        }

        group.enter()
        fetchData { (data) in
            print("Fetch Data - 2 @",data)
            group.leave()
        }

        group.notify(queue: .main) {
            print("Finish Fetch")
        }

Kullanımı oldukça basit. DispatchGroup sınıfına bağlı değişken ile yürütülecek işlem öncesi .enter() fonksiyonu ile Proses başlatıp işlem bitiminde diğer Prosese geçmesi için .leave() fonksiyonu ile tamamlıyoruz. Tüm yürütülen prosesler sonlandığı zaman .notify() block içerisinde kullanıcıya bilgilendirme işlemi yapabilirsiniz.

Semaphore yapısı ile aynı işlemleri gerçekleştirelim.

let semaphore = DispatchSemaphore(value: 0)
        let queue = DispatchQueue.global(qos: .background)

        queue.async {
            self.fetchData { (data) in
                print("Fetch Data - 1 @",data)
                semaphore.signal()
            }
            semaphore.wait()
            self.fetchData { (data) in
                print("Fetch Data - 2 @",data)
                semaphore.signal()
            }
            semaphore.wait()
            self.fetchData { (data) in
                print("Fetch Data - 3 @",data)
                semaphore.signal()
            }
            semaphore.wait()
            print("Finish Fetch")
        }

Yapıların benzediğini söylemiştim. işlem bittiği zaman .signal() ile işlemi tetikleyip .wait() fonksiyonu aşağısında olan kısmı çalıştırabilirsiniz. DispatchSemaphore içerisinde bulunan value değeri 0 olduğu zaman tüm işlemleri teker teker yürütür. Ancak değeri yükselttiğiniz zaman yapılacak işlemi block dışında tutar. Bu konuda Group yapısından ayrışmaktadır.

Aşağıda verdiğimiz değerlere göre yürütülen işlem yapısını görebilirsiniz.

Value değeri 0 olduğu zaman;

Fetch Data - 1 @ 308 bytes
Fetch Data - 2 @ 308 bytes
Fetch Data - 3 @ 308 bytes
Finish Fetch

Value değeri 2 olduğu zaman;

Fetch Data - 1 @ 308 bytes
Finish Fetch
Fetch Data - 3 @ 308 bytes
Fetch Data - 2 @ 308 bytes

 

 

 

Tarih:iOS

İlk Yorumu Siz Yapın

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Copyright © 2020 Kenan Atmaca