Middle+
Yarış şərti (race condition) problemini necə həll etmək olar?
sobes.tech Süni İntellekt
AI-dan cavab
Ümumi resurslara giriş üçün axınların sinxronizasiyasından istifadə etmək.
Əsas yanaşmalar:
- Mutexlər (Müəyyənləşdiricilər): Bir axın resursu istifadə etdikdə, digər axınların ona girişini bloklayır.
NSLockos_unfair_lockpthread_mutex_t
import Foundation
let lock = NSLock()
var sharedResource = 0
func modifyResource() {
lock.lock() // Müəyyənləşdiricini ələ keçirmək
// Kritikal bölmə - sharedResource-ə təhlükəsiz giriş
sharedResource += 1
print("Resurs dəyəri: \(sharedResource)")
lock.unlock() // Müəyyənləşdiricini azad etmək
}
// Fərqli axınlardan çağırış nümunəsi
// DispatchQueue.global().async { modifyResource() }
// DispatchQueue.global().async { modifyResource() }
- Serial Queue-lar (Serial növbələr): Tapşırıqları bir-bir yerinə yetirir, eyni zamanda yalnız bir blok kod resursa giriş edə bilər.
DispatchQueue.mainDispatchQueue.global()və.serialatributu ilə
import Foundation
let serialQueue = DispatchQueue(label: "com.example.serialQueue")
var sharedResource = 0
func modifyResourceAsync() {
serialQueue.async {
// Kod ardıcıllıqla icra olunur
sharedResource += 1
print("Resurs dəyəri: \(sharedResource)")
}
}
// Fərqli axınlar/növbələrdən çağırış nümunəsi
// modifyResourceAsync()
// modifyResourceAsync()
- Oxucu-Yazıcı Lock-ləri (Reader-Writer Locks): Bir çox axın resuru oxuya bilər, amma yalnız bir axın yaza bilər.
DispatchQueuevə.barrierilə yazma və oxuma üçün sinxron və asinxron giriş.
import Foundation
let concurrentQueue = DispatchQueue(label: "com.example.concurrentQueue", attributes: .concurrent)
var sharedResource = 0
func readResource() {
concurrentQueue.async { // Oxuma - çox oxucu eyni zamanda
print("Resursu oxuyur: \(sharedResource)")
}
}
func writeResource(newValue: Int) {
concurrentQueue.sync(flags: .barrier) { // Yazma - yalnız bir yazar və heç kim oxumur/yazmır
sharedResource = newValue
print("Resursu yazır: \(sharedResource)")
}
}
// Çağırış nümunələri
// readResource()
// readResource()
// writeResource(newValue: 10)
// readResource()
- Atomik Əməliyyatlar (Atomic Operations): Bir axın tərəfindən tam və kəsilmədən yerinə yetirilən əməliyyatlar. Sadə tipli məlumatlar üçün istifadə olunur (sayğaclar, bayraqlar).
OSAtomicIncrement,OSAtomicDecrement(Köhnə olsa da, konsept aktualdır)- C++11
<atomic>
#include <atomic>
#include <iostream>
std::atomic<int> atomicCounter(0);
void incrementCounter() {
atomicCounter++; // Atomik artım
std::cout << "Sayğac: " << atomicCounter << std::endl;
}
// iOS kontekstində C++ nümunəsi (Objective-C++ ilə istifadə)
// Fərqli axınlardan çağırmaq
- Dəyər Növləri (Value Types): Strukturların və ya enumerasiyaların nüsxələrini ötürmək, məlumatların yarışmasını qarşısını almağa kömək edə bilər, əgər məlumatlar birbaşa paylaşılmırsa və dəyişdirilməzdirsə.
Yöntəmin seçimi vəzifənin xüsusiyyətlərinə və tələb olunan paralellik səviyyəsinə bağlıdır. iOS-də əksər hallarda DispatchQueue (Serial və Concurrent, barierlərlə) istifadə etmək daha asandır və Grand Central Dispatch (GCD) ilə inteqrasiya olunur.