2017-06-12 5 views
0

Dans un langage de programmation non-OOP, comme C, si on laisse uniquement muter les variables locales de toutes les façons possibles (changer les champs internes, réattribuer, ...) mais interdire la mutation des arguments de fonction, cela nous aidera-t-il? empêcher l'état mutable partagé?Pouvons-nous empêcher l'état mutable partagé si nous permettons seulement aux variables locales d'être mutables?

Notez que dans ce cas, la fonction main peut démarrer 10 threads (fonctions) et chacun de ces 10 threads recevra une référence immuable à la même variable (définie dans main). Mais la fonction main peut toujours changer la valeur de cette variable partagée. Alors, cela peut-il causer un problème dans un logiciel concurrent/parallèle?

J'espère que la question est claire, mais laissez-moi savoir si ce n'est pas le cas.

P.S. La "mémoire transactionnelle logicielle (STM)" peut-elle résoudre les problèmes potentiels? Comme ce qu'offre Clojure?

+2

'main' n'est pas différent des autres threads. Vous avez donc exactement les mêmes problèmes multi-thread dans le cas décrit que vous avez si les threads individuels modifient une variable partagée. – 4386427

+1

@ 4386427 Notez l'hypothèse qu'un seul thread est autorisé à écrire dans la mémoire. Tous les autres fils ne lisent que ... Il y a encore des problèmes (j'écris une réponse), mais souvent les gens croient que cela aide. – Myst

+1

Si 'main()' modifie la variable mais que les threads sont censés lire des valeurs différentes, vous n'avez pas résolu le problème. Cela peut poser un problème avec les pthreads POSIX. La fonction 'pthread_create()' prend un dernier argument 'void *', et une erreur courante est de passer l'adresse d'une variable de contrôle en boucle - ce qui signifie que les threads ne peuvent pas dire ce qu'ils lisent (la valeur peut avoir changé entre le moment où la fonction a été invoquée et le démarrage du thread). –

Répondre

2

Oui et non ... cela dépend de la plate-forme, du processeur, de la taille de la variable partagée et du compilateur.

Sur une NVIDIA forum, par rapport aux opérations de GPU, une question similaire a été très soigneusement répondu:

Lorsque plusieurs threads écriture ou la lecture vers/à partir d'un emplacement naturellement aligné dans la mémoire globale, et le type de données étant lu ou écrit est le même par tous les threads, et le type de données correspond à l'un des types pris en charge pour l'accès au fil instruction unique ...

(Beaucoup GPU instruction unique peut gérer 16 mots d'octets (128 bits) lorsque il est connu à l'avance, mais la plupart des processeurs utilisent 32 bits ou une seule instruction limites 64bit)

Je laisse de côté la possibilité que les discussions pourraient lire à partir du CPU registres au lieu de la mémoire réelle (sans tenir compte des mises à jour aux données), celles-ci sont pour la plupart résoluble en utilisant le mot-clé dans volatile C.

Cependant, les conflits et la corruption de la mémoire peuvent encore se produire.

Certaines opérations de stockage de mémoire sont gérées en interne (par la CPU) ou par votre compilateur (le code machine) en utilisant un certain nombre d'appels de stockage. Dans ces cas, la plupart du temps sur des machines multicœurs (mais pas seulement), il y a le risque que le "lecteur" reçoive des informations partiellement mises à jour et qui n'ont aucune signification (ie, la moitié d'un pointeur est valide et l'autre ne l'est pas).

Les variables plus grandes que 32 bits ou 64 bits habituellement sont mises à jour un "mot" de CPU (pas un mot OS) à la fois (32 bits ou 64 bits).

Les variables de taille octet sont très sûres, c'est pourquoi elles sont souvent utilisées comme drapeaux ... mais elles doivent probablement être gérées en utilisant les opérations de stockage/écriture atomic_* fournies par le système d'exploitation ou le compilateur.

+0

Can "logiciel de mémoire transactionnelle (STM)" résoudre les problèmes potentiels? Comme ce qu'offre Clojure? – mahdix

+0

@mahdix - STM pourrait vous protéger (puisque les logs et les données ne rentreront pas, donc un rollback sera effectué) ... mais il s'agit généralement d'une fonctionnalité de langue. Il peut être implémenté en C (c'est probablement le cas), mais c'est juste une alternative à l'utilisation de verrous ... À mon humble avis, pas même une très bonne alternative. C n'automatisera pas l'utilisation de la STM (ce qui bat un peu son but, si vous me le demandez), donc vous devrez entourer chaque opération de lecture et d'écriture avec la logique STM. – Myst