Une course de données se produit lorsque deux ou plusieurs fils ont accès à des données partagées dans lesquels au moins un est une opération d'écriture dans laquelle un ou plusieurs fils peuvent rencontrer un état incohérent.
Le code fourni a deux mutex, un pour la lecture et un pour l'écriture. Cela n'exclut en aucun cas un thread de lire les données partagées (var1
, var2
dans l'exemple) alors qu'un autre leur écrit ou plus précisément après avoir commencé à écrire sur l'un d'entre eux et avant d'avoir fini d'écrire dans l'autre dans une situation où cet état intermédiaire serait considéré comme un état incohérent dans les paramètres de la logique du code et son but. Un mutex
est requis pour que la lecture et l'écriture soient exclusives. En aparté, on ne sait pas pourquoi un mutex récursif a été déclaré. Cela ne serait nécessaire que si un thread donné rencontrait un code l'obligeant à obtenir un mutex qu'il détient déjà. C'est mieux de concevoir et de coder cette situation là où c'est possible.
explicite unlock
mesures ont été introduites qui peuvent ou peuvent ne pas être explicitement en fonction du modèle de codage (requis en C, utiliser std::lock_guard
en C++ ou synchronized
ou finally
en Java, etc.).
Une condition a été introduite pour indiquer une condition de terminaison appropriée. while(true)
est une mauvaise pratique à moins qu'une autre condition ne le termine gracieusement.
Des modèles plus sophistiqués peuvent utiliser un 'mutex partagé' dans lequel plus d'un thread peut le maintenir en mode 'read' mais un seul si on le maintient en mode 'write'. Cela peut nécessiter ou non une certaine signalisation pour s'assurer que 'write' n'entrera pas dans un live-lock où de nombreux lecteurs bloquent indéfiniment l'accès 'write'.
mutex mutex_v1_v2 //The mutex controlling shared state var1, var2.
var1, var2
//called every 50ms
onUpdateListener() {
lock(mutex_v1_v2)
update var1
update var2
unlock(mutex_v1_v2)
}
VarReaderThread::readVar() {
sleep(50)
while(!finished) {
lock(mutex_v1_v2)
read var1
read var2
unlock(mutex_v1_v2)
sleep(50) //V. V. important to sleep not holding the mutex!
}
}
La 'portée' de vos mutex n'est pas claire. –
Pourquoi utiliser ces mutex? Y a-t-il d'autres codes accédant aux vars? Parce que dans ce scénario, ils sont totalement inutiles. –
Vous ne devriez pas écrire et lire en même temps ou vous pourriez rencontrer un état incohérent (condition de concurrence). Vous ne devriez pas écrire et écrire en même temps, même si la lecture et la lecture peuvent être effectuées simultanément. L'écriture ne se mélange pas. L'utilisation de verrous séparés pour la lecture et l'écriture n'aidera pas. comme le suggère @HenkHolterman dans ce code, ces mutex ne font rien. – Persixty