Sobes.tech
Middle+

Race condition маселесин кантип чечүү керек?

sobes.tech AI

AIден жооп

Жалпы ресурстарга кирүү үчүн жиптердин синхрондоштуусун колдонуу.

Негизги ыкмалар:

  • Mutexтер (Мьютекстер): Бир жип ресурска кирүүнү башка жиптер үчүн бөгөттөйт, ал эми бир жип аны колдонуп жатканда.
    • NSLock
    • os_unfair_lock
    • pthread_mutex_t
import Foundation

let lock = NSLock()
var sharedResource = 0

func modifyResource() {
    lock.lock() // Мьютексти алуу
    // Критикалык бөлүм - коопсуз жетүү sharedResource
    sharedResource += 1
    print("Ресурс мааниси: \(sharedResource)")
    lock.unlock() // Мьютексти бошотуу
}

// Төрттүрдүү жиптерден чакыруу мисалы
// DispatchQueue.global().async { modifyResource() }
// DispatchQueue.global().async { modifyResource() }
  • Serial кезектери (Serial Queues): Иштерди биринин артынан аткарып, бир убакта бир гана код блогу ресурска жеткиликтүү экенин камсыздайт.
    • DispatchQueue.main
    • DispatchQueue.global() .serial мүнөздөмөсү менен
import Foundation

let serialQueue = DispatchQueue(label: "com.example.serialQueue")
var sharedResource = 0

func modifyResourceAsync() {
    serialQueue.async {
        // Код кезекке салынган
        sharedResource += 1
        print("Ресурс мааниси: \(sharedResource)")
    }
}

// Төрттүрдүү жиптерден чакыруу мисалы
// modifyResourceAsync()
// modifyResourceAsync()
  • Окуучу-жазуучу (Reader-Writer) Lock-тер: Бир нече жиптер ресурсты бир убакта окуй алат, бирок жазуу үчүн бир гана жип уруксат алат.
    • DispatchQueue .barrier менен жазуу жана окуу үчүн синхрондук/асинхрондук жеткиликтүүлүк.
import Foundation

let concurrentQueue = DispatchQueue(label: "com.example.concurrentQueue", attributes: .concurrent)
var sharedResource = 0

func readResource() {
    concurrentQueue.async { // Окуу - бир нече окууучу бир убакта
        print("Ресурсты окуу: \(sharedResource)")
    }
}

func writeResource(newValue: Int) {
    concurrentQueue.sync(flags: .barrier) { // Жазуу - бир гана жазуучу жана эч ким окубайт/жазбайт
        sharedResource = newValue
        print("Ресурс жазуу: \(sharedResource)")
    }
}

// Чакыруулар мисалы
// readResource()
// readResource()
// writeResource(newValue: 10)
// readResource()
  • Атомардык операциялар: Башка жиптердин аралашуусуз толук жана үзгүлтүксүз аткарылуучу операциялар.
    • OSAtomicIncrement, OSAtomicDecrement (Эскирген, бирок концепциясы актуалдуу)
    • C++11 <atomic>
#include <atomic>
#include <iostream>

std::atomic<int> atomicCounter(0);

void incrementCounter() {
    atomicCounter++; // Атомардык көбөйтүү
    std::cout << "Санаачык: " << atomicCounter << std::endl;
}

// iOS контекстинде C++ мисалы (Objective-C++ менен колдонуу)
// Төрттүрдүү жиптерден чакыруу
  • Маани түрлөрү (Value Types): Структуралардын жана энумерациялардын көчүрмөлөрүн өткөрүү, маалыматтардын таймашуусун алдын алууга жардам берет, эгерде маалыматтар түздөн-түз бөлүшүлбөсө жана өзгөрүлмө түрдө бөлүшүлбөсө.

Методду тандоо иштин өзгөчөлүктөрүнө жана талап кылынган параллелизм деңгээлине көз каранды. iOS үчүн көбүнчө DispatchQueue (Serial жана Concurrent, барьерлер менен) колдонуу сунушталат, анткени ал колдонууга оңой жана Grand Central Dispatch (GCD) менен жакшы интеграцияланган.