Je travaille sur une implémentation d'exécution JavaScript multi-thread depuis une semaine. J'ai une preuve de concept faite en C ++ en utilisant JavaScriptCore et boost.
L’architecture est simple: lorsque le moteur d’exécution termine l’évaluation du script principal, il se lance et rejoint un pool de threads, qui commence à sélectionner des tâches dans une file d’attente de priorité partagée. .
Le problème est que lorsque je présente cette conception à un programmeur JavaScript, je reçois des commentaires extrêmement négatifs et je ne sais pas pourquoi. Même en privé, ils disent tous que JavaScript est censé être à thread unique, que les bibliothèques existantes devront être réécrites, et que les gremlins apparaîtront et mangeront tous les êtres vivants si je continue à travailler là-dessus.
J'avais à l'origine une implémentation coroutine native (utilisant des contextes boostés) également, mais je devais l'abandonner (JavaScriptCore est pédant à propos de la pile), et je ne voulais pas risquer leur colère, j'ai donc décidé de ne pas le mentionner.
Qu'est-ce que tu penses? JavaScript est-il censé être à thread unique et doit-il être laissé seul? Pourquoi tout le monde s'oppose-t-il à l'idée d'une exécution simultanée de JavaScript?
Edit: Le projet est maintenant sur GitHub , testez -le vous-même et dites-moi ce que vous pensez.
Vous trouverez ci-dessous une image des promesses exécutées sur tous les cœurs de la CPU en parallèle, sans contention:
la source
Réponses:
1) Le multithreading est extrêmement difficile et, malheureusement, la façon dont vous avez présenté cette idée jusqu'à présent implique que vous sous-estimez sévèrement à quel point c'est difficile.
Pour le moment, on dirait que vous "ajoutez simplement des fils" au langage et que vous vous demandez comment le rendre correct et performant plus tard. En particulier:
Ajouter des discussions à Javascript sans "solution au problème de synchronisation" équivaudrait à ajouter des entiers à Javascript sans "solution au problème de l'addition". La nature même du problème est tellement fondamentale qu’il est en définitive inutile de discuter de la question de savoir si le multithreading vaut la peine d’être ajouté sans solution spécifique à l’esprit, peu importe à quel point nous le voudrions.
De plus, rendre toutes les variables atomiques est le genre de chose qui rendrait un programme multithread moins performant que son homologue monofil-lu, ce qui rend encore plus important de tester les performances sur des programmes plus réalistes et de voir si vous gagnez quelque chose ou non.
Je ne vois pas non plus clairement si vous essayez de masquer les discussions au programmeur node.js ou si vous prévoyez de les exposer à un moment donné, créant ainsi un nouveau dialecte Javascript pour la programmation multithread. Les deux options sont potentiellement intéressantes, mais il semblerait que vous n’ayez pas encore décidé laquelle vous visiez.
Donc, pour le moment, vous demandez aux programmeurs d’envisager de passer d’un environnement à un seul thread à un nouvel environnement multithread qui n’a pas de solution pour le problème de synchronisation ni aucune preuve qu’il améliore les performances dans le monde réel, et apparemment aucun plan pour résoudre ces problèmes.
C'est probablement pourquoi les gens ne vous prennent pas au sérieux.
2) La simplicité et la robustesse de la boucle d’événement unique constituent un avantage considérable .
Les programmeurs Javascript savent que le langage Javascript est "à l'abri" des conditions de concurrence et d'autres bugs extrêmement insidieux qui minent toute programmation véritablement multithread. Le fait qu’ils aient besoin d’arguments solides pour les convaincre d’abandonner cette sécurité ne les rend pas fermés d’esprit, ils les rendent responsables.
À moins que vous ne puissiez conserver cette sécurité, quiconque voudra passer à un nœud multithread sera probablement mieux de passer à un langage tel que Go, conçu dès le départ pour les applications multithread.
3) Javascript supporte déjà les "threads d'arrière-plan" (WebWorkers) et la programmation asynchrone sans exposer directement la gestion des threads au programmeur.
Ces fonctionnalités résolvent déjà de nombreux cas d'utilisation courants qui affectent les programmeurs Javascript dans le monde réel, sans pour autant renoncer à la sécurité de la boucle d'événement unique.
Avez-vous des cas d'utilisation spécifiques à l'esprit que ces fonctionnalités ne résolvent pas et pour lesquelles les programmeurs Javascript veulent une solution? Si tel est le cas, il serait judicieux de présenter votre fichier node.js multithread dans le contexte de ce cas d'utilisation spécifique.
Post-scriptum Qu'est-ce qui me convaincrait d'essayer de passer à une implémentation multithread de node.js?
Ecrivez un programme non-trivial dans Javascript / node.js qui, selon vous, bénéficierait d'un véritable multithreading. Effectuez des tests de performances sur cet exemple de programme dans un noeud normal et votre noeud multithread. Montrez-moi que votre version améliore considérablement les performances d'exécution, la réactivité et l'utilisation de plusieurs cœurs, sans introduire de bogues ni d'instabilité.
Une fois que vous avez fait cela, je pense que vous verrez des gens beaucoup plus intéressés par cette idée.
la source
Devinez juste ici pour démontrer un problème dans votre approche. Je ne peux pas le tester contre la mise en œuvre réelle car il n'y a pas de lien nulle part ...
Je dirais que c'est parce que les invariants ne sont pas toujours exprimés par la valeur d'une variable et que "une variable" n'est pas suffisant pour être la portée d'un verrou dans le cas général. Par exemple, imaginons que nous ayons un invariant
a+b = 0
(le solde d’une banque avec deux comptes). Les deux fonctions ci-dessous garantissent que l'invariant est toujours maintenu à la fin de chaque fonction (l'unité d'exécution dans JS à un seul thread).Maintenant, dans votre monde multithread, ce qui se passe lorsque deux threads exécutent
withdraw
etdeposit
en même temps? Merci, Murphy ...(Vous pourriez avoir un code qui traite spécialement les + = et - =, mais ce n'est pas une aide. À un moment donné, vous aurez un état local dans une fonction, et avec aucun moyen de "verrouiller" deux variables en même temps, votre volonté invariante être violé.)
ÉDITER: si votre code est sémantiquement équivalent au code Go à l’ adresse https://gist.github.com/thriqon/f94c10a45b7e0bf656781b0f4a07292a , mon commentaire est exact ;-)
la source
Il y a une dizaine d'années, Brendan Eich (l'inventeur de JavaScript) a écrit un essai intitulé Threads Suck , qui est certainement l'un des rares documents canoniques de la mythologie du design de JavaScript.
Une autre question est de savoir si elle est correcte, mais je pense que cela a eu une grande influence sur la façon dont la communauté JavaScript pense à la simultanéité.
la source
L'accès atomique ne se traduit pas par un comportement thread-safe.
Un exemple est le cas lorsqu'une structure de données globale doit être invalide lors d'une mise à jour, telle que le rehachage d'une table de hachage (lors de l'ajout d'une propriété à un objet, par exemple) ou le tri d'un tableau global. Pendant ce temps, vous ne pouvez autoriser aucun autre thread à accéder à la variable. Cela signifie essentiellement que vous devez détecter tous les cycles lecture-mise à jour-écriture et les verrouiller. Si la mise à jour est non triviale, cela finira par arrêter le territoire du problème.
Le Javascript a été unifié et a été sandboxé depuis le début et tout le code est écrit en tenant compte de ces hypothèses.
Cela présente un grand avantage en ce qui concerne les contextes isolés et permet à deux contextes distincts de s'exécuter dans des threads différents. Cela signifie également que les personnes qui écrivent en javascript n'ont pas besoin de savoir comment faire face aux conditions de course et à d'autres pitfals multi-thread.
la source
Votre approche va-t-elle améliorer considérablement les performances?
Douteux. Vous devez vraiment le prouver.
Votre approche va-t-elle faciliter l'écriture de code?
Certainement pas, le code multithread est beaucoup plus difficile à obtenir que le code à un seul thread.
Votre approche sera-t-elle plus robuste?
Les impasses, les conditions de course, etc. sont un cauchemar à réparer.
la source
Votre implémentation ne consiste pas seulement à introduire la simultanéité, mais plutôt à introduire un moyen spécifique pour implémenter la simultanéité, c’est-à-dire la simultanéité par état mutable partagé. Au cours de l'histoire, les gens ont eu recours à ce type de concurrence, ce qui a entraîné de nombreux problèmes. Bien sûr, vous pouvez créer des programmes simples qui fonctionnent parfaitement avec l’utilisation de la simultanéité d’états mutables partagés, mais le véritable test de tout mécanisme n’est pas ce qu’il peut faire, mais il peut évoluer à mesure que le programme se complexifie et que de plus en plus de fonctionnalités sont ajoutées au programme. Rappelez-vous que les logiciels ne sont pas des objets statiques que vous construisez une fois et que vous en avez fini, mais qu’ils évoluent avec le temps et si un mécanisme ou un concept le permet.
Vous pouvez examiner d’autres modèles de concurrence (par exemple, la transmission de messages) pour vous aider à déterminer les avantages qu’ils procurent.
la source
C'est nécessaire. L'absence d'un mécanisme d'accès simultané de bas niveau dans le noeud js limite ses applications dans des domaines tels que les mathématiques et la bioinformatique, etc. En outre, une concurrence d'accès avec des threads n'entre pas nécessairement en conflit avec le modèle de concurence par défaut utilisé dans node. Il existe une sémantique bien connue pour les threads dans un environnement avec une boucle d'événement principale, telle que les frameworks ui (et nodejs), et même s'ils sont trop complexes pour la plupart des situations, ils ont toujours des utilisations valables.
Bien sûr, votre application Web moyenne ne nécessitera pas de threads, mais essayez de faire quelque chose de moins conventionnel, et l'absence d'une primitive de concurrence à bas niveau sonore vous éloignera rapidement de quelque chose qui la propose.
la source
Je crois vraiment que c'est parce que c'est une idée différente et puissante. Vous allez contre les systèmes de croyance. Les choses deviennent acceptées ou populaires via le réseau affecte non pas sur la base du mérite. De plus, personne ne veut s’adapter à une nouvelle pile. Les gens rejettent automatiquement les choses trop différentes.
Si vous pouvez trouver un moyen de le transformer en un module npm normal qui semble peu probable, certaines personnes l'utiliseront peut-être.
la source