O que é uma condição de corrida (race condition)?
sobes.tech IA
Resposta da IA
A condição de corrida ocorre quando dois ou mais threads ou processos acedem simultaneamente a um recurso partilhado (por exemplo, uma variável, um ficheiro, uma base de dados) e o resultado da operação depende da ordem em que esses threads/processos realizam as suas ações. Devido à ordem imprevisível de acesso e modificação de dados, o resultado pode ser incorreto ou inesperado.
Exemplo em iOS:
Suponha que temos um contador count, ao qual acedem simultaneamente dois threads para o incrementar.
var count = 0
func incrementCount() {
// Thread 1 lê count = 5
// Thread 2 lê count = 5
let currentCount = count
// Thread 1 calcula newCount = 6
// Thread 2 calcula newCount = 6
let newCount = currentCount + 1
// Thread 1 escreve count = 6
// Thread 2 escreve count = 6 (sobre-escrevendo o resultado do Thread 1)
count = newCount
}
// Se dois threads chamarem incrementCount() simultaneamente,
// o resultado esperado seria count = 2,
// mas devido à condição de corrida, count pode tornar-se 1.
Para evitar condições de corrida, utilizam-se mecanismos de sincronização:
- Lock/Mutex: Bloqueia o acesso ao recurso enquanto o thread o utiliza.
import Foundation let lock = NSLock() var count = 0 func incrementCount() { lock.lock() // Adquire o bloqueio let currentCount = count let newCount = currentCount + 1 count = newCount lock.unlock() // Liberta o bloqueio } - Filas (Queues): Utilização de filas GCD sequenciais.
import Foundation let serialQueue = DispatchQueue(label: "com.myapp.counterQueue") var count = 0 func incrementCount() { serialQueue.async { let currentCount = count let newCount = currentCount + 1 count = newCount } } - Operações atómicas: Operações indivisíveis ao nível das instruções do processador. Em Swift, pode-se usar
OSAtomic...(obsoleto) ouAtomicde@_implementationOnly import Atomics(experimental), ou abordagens baseadas em bloqueios/filas.
A escolha do método de sincronização depende do cenário específico e dos requisitos de desempenho. É importante entender que a sincronização pode introduzir carga adicional e potencialmente levar a bloqueios mútuos (deadlocks) se não for implementada corretamente.