Swift'te iş parçacığı güvenliği sağlamak için genellikle GCD (Grand Central Dispatch) ve kuyruklar (DispatchQueue), NSLock ve modern mekanizmalar, örneğin actor (Swift 5.5 itibarıyla) kullanılır.
Ana fikir – değişken verilere erişim ya yalnızca ardışık sıralarla ya da senkronizatörler (kilitler) kullanılarak gerçekleşir.
GCD ile örnek:
class ThreadSafeArray<Element> { private var array: [Element] = [] private let queue = DispatchQueue(label: "com.example.arrayQueue", attributes: .concurrent) func append(_ item: Element) { queue.async(flags: .barrier) { self.array.append(item) } } func get(index: Int) -> Element? { var result: Element? queue.sync { result = self.array.indices.contains(index) ? self.array[index] : nil } return result } }
Modern yaklaşım: Aktörler (Swift 5.5+):
actor SafeCounter { private var value = 0 func increment() { value += 1 } func get() -> Int { return value } }
Her iki yaklaşım da veri yarışlarını önleyerek durumun tutarlılığını korur.
Soru:
Eğer
DispatchQueue.syncana kuyruğun içinde kullanıyorsanız ne olur ve neden?
Cevap: Deadlock ortaya çıkar çünkü Ana Kuyruk zaten bir görevi yerine getiriyor ve aynı kuyrukta senkron bir işlemin tamamlanmasını bekliyor. Dolayısıyla, kuyruk mevcut görevi tamamlamadan yeni bir görevi işleyemez ve bu asla gerçekleşmeyecektir.
Örnek:
DispatchQueue.main.sync { // Deadlock: bu satır asla çalışmayacak }
Hikaye
Projede, eş zamanlı olarak birden fazla iş parçacığından erişilen değişken bir koleksiyon kullanıldı, bunun sonucunda uygulama çöküşlerine ve veri yarışlarından dolayı zorlayıcı hatalara yol açtı: zaman zaman öğeler kayboldu, bazen de dizinin dışına çıkıldı.
Hikaye
Geliştirici, çalışma zamanında ana kuyruğun üzerinde DispatchQueue.sync'i yanlış bir şekilde kullandı, bu da deadlock ve kullanıcıların arayüzünün tamamen kilitlenmesine neden oldu. Acil bir düzeltme ve sürüm geri alma gerekiyordu.
Hikaye
NSLock kullanarak bir sınıfı iş parçacığı güvenli hale getirmeye çalışırken, metodun tüm çıkış yolları için lock/unlock uygulamasını unuttular (örneğin, hata veya guard içindeki return durumunda), bu da deadlock potansiyeli ve uygulamanın performansında ciddi sorunlara yol açtı.