J'ai vu ce lien: Implémentation de l'exclusion mutuelle en JavaScript . D'un autre côté, j'ai lu qu'il n'y a pas de threads en javascript, mais qu'est-ce que cela signifie exactement?
Lorsque des événements se produisent, où dans le code peuvent-ils s'interrompre?
Et s'il n'y a pas de threads dans JS, dois-je utiliser des mutex dans JS ou non?
Plus précisément, je me demande sur les effets de l' utilisation des fonctions appelées par setTimeout()
et XmlHttpRequest
« s onreadystatechange
sur des variables globalement accessibles.
Réponses:
Javascript est défini comme un langage réentrant , ce qui signifie qu'aucun thread n'est exposé à l'utilisateur, il peut y avoir des threads dans l'implémentation. Les fonctions telles
setTimeout()
que les rappels asynchrones doivent attendre que le moteur de script se mette en veille avant de pouvoir s'exécuter.Cela signifie que tout ce qui se passe dans un événement doit être terminé avant que l'événement suivant ne soit traité.
Cela étant dit, vous pouvez avoir besoin d'un mutex si votre code fait quelque chose où il s'attend à ce qu'une valeur ne change pas entre le moment où l'événement asynchrone a été déclenché et le moment où le rappel a été appelé.
Par exemple, si vous avez une structure de données où vous cliquez sur un bouton et qu'elle envoie une XmlHttpRequest qui appelle un rappel, la structure de données change de manière destructive, et vous avez un autre bouton qui change directement la même structure de données, entre le moment où l'événement a été déclenché et lorsque le rappel a été exécuté, l'utilisateur aurait pu cliquer et mettre à jour la structure de données avant le rappel, ce qui pouvait alors perdre la valeur.
Bien que vous puissiez créer une condition de concurrence comme celle-là, il est très facile de l'empêcher dans votre code car chaque fonction sera atomique. Ce serait beaucoup de travail et nécessiterait des modèles de codage étranges pour créer la condition de concurrence en fait.
la source
Les réponses à cette question sont un peu dépassées bien que correctes au moment où elles ont été données. Et toujours correct si vous regardez une application javascript côté client qui n'utilise PAS de webworkers.
Articles sur les web-workers:
multithreading en javascript avec les webworkers
Mozilla sur les webworkers
Cela montre clairement que javascript via des web-workers a des capacités de multithreading. En ce qui concerne la question, les mutex sont-ils nécessaires en javascript? Je n'en suis pas sûr. Mais ce post de stackoverflow semble pertinent:
Exclusion mutuelle pour N threads asynchrones
la source
Comme le souligne @william,
Cela peut être généralisé davantage - si votre code fait quelque chose où il attend le contrôle exclusif d'une ressource jusqu'à ce qu'une requête asynchrone soit résolue, vous aurez peut-être besoin d'un mutex.
Un exemple simple est celui où vous avez un bouton qui déclenche un appel ajax pour créer un enregistrement dans le back-end. Vous aurez peut-être besoin d'un peu de code pour vous empêcher de déclencher des utilisateurs satisfaits en cliquant et de créer ainsi plusieurs enregistrements. il existe un certain nombre d'approches à ce problème (par exemple, désactiver le bouton, activer en cas de succès ajax). Vous pouvez également utiliser un simple verrou:
Je ne sais pas si c'est la meilleure approche et je serais intéressé de voir comment les autres gèrent l'exclusion mutuelle en javascript, mais pour autant que je sache, c'est un simple mutex et c'est pratique.
la source
while
avecsetTimeout
ou unsetInterval
avecclearInterval
après n échecs afin que vous ayez une logique de nouvelle tentative et de délai d'attente. Laisser tel quel signifie que vous contournerez simplement le code verrouillé. La gestion externe des mutex et des objets partagés est aussi importante que les implémentations elles-mêmes.JavaScript est un thread ... bien que Chrome soit peut-être une nouvelle bête (je pense que c'est aussi un thread unique, mais chaque onglet a son propre thread JavaScript ... Je ne l'ai pas examiné en détail, alors ne me citez pas Là).
Cependant, une chose dont vous devez vous soucier est de savoir comment votre JavaScript gérera plusieurs demandes ajax qui ne reviennent pas dans le même ordre que vous les envoyez. Donc, tout ce dont vous devez vraiment vous soucier est de vous assurer que vos appels ajax sont traités de manière à ne pas marcher sur les pieds l'un de l'autre si les résultats reviennent dans un ordre différent de celui que vous leur avez envoyé.
Cela vaut aussi pour les délais d'attente ...
Lorsque JavaScript développe le multithreading, vous vous inquiétez peut-être des mutex et autres ....
la source
Oui, des mutex peuvent être requis en Javascript lors de l'accès aux ressources partagées entre les onglets / fenêtres, comme localStorage .
Par exemple, si un utilisateur a deux onglets ouverts, un code simple comme celui-ci n'est pas sûr:
Entre le moment où l'élément localStorage est «obtenu» et «défini», un autre onglet peut avoir modifié la valeur. C'est généralement peu probable, mais possible - vous devrez juger par vous-même de la probabilité et du risque associés à toute contestation dans votre situation particulière.
Consultez les articles suivants pour plus de détails:
la source
JavaScript, le langage , peut être aussi multithread que vous le souhaitez, mais les intégrations de navigateur du moteur javascript n'exécutent qu'un seul rappel (onload, onfocus, <script>, etc ...) à la fois (par onglet, probablement). La suggestion de William d'utiliser un Mutex pour les changements entre l'enregistrement et la réception d'un rappel ne doit pas être prise trop littéralement à cause de cela, car vous ne voudriez pas bloquer le rappel intervenant car le rappel qui le déverrouillera sera bloqué derrière le rappel actuel ! (Wow, l'anglais est nul pour parler de threading.) Dans ce cas, vous voudrez probablement faire quelque chose comme la redistribution de l'événement actuel si un drapeau est défini, soit littéralement, soit avec setTimeout ().
Si vous utilisez une intégration différente de JS et que vous exécutez plusieurs threads à la fois, cela peut devenir un peu plus risqué, mais en raison de la façon dont JS peut utiliser les rappels si facilement et verrouille les objets sur l'accès aux propriétés, le verrouillage explicite n'est pas aussi nécessaire . Cependant, je serais surpris si une intégration conçue pour du code général (par exemple, des scripts de jeu) qui utilisait le multi-threading ne donnait pas également des primitives de verrouillage explicites.
Désolé pour le mur de texte!
la source
Les événements sont signalés, mais l'exécution de JavaScript est toujours monothread.
Je crois comprendre que lorsqu'un événement est signalé, le moteur arrête ce qu'il exécute en ce moment pour exécuter le gestionnaire d'événements. Une fois le gestionnaire terminé, l'exécution du script reprend. Si le gestionnaire d'événements a modifié certaines variables partagées, le code repris verra ces modifications apparaître «à l'improviste».
Si vous voulez "protéger" les données partagées, un simple drapeau booléen devrait suffire.
la source