Est-ce une décision de conception délibérée ou un problème avec nos navigateurs actuels qui sera corrigé dans les prochaines versions?
Est-ce une décision de conception délibérée ou un problème avec nos navigateurs actuels qui sera corrigé dans les prochaines versions?
Réponses:
JavaScript ne prend pas en charge le multithread car l'interpréteur JavaScript dans le navigateur est un thread unique (AFAIK). Même Google Chrome ne laissera pas le JavaScript d'une seule page Web s'exécuter simultanément, car cela entraînerait d'énormes problèmes de concurrence dans les pages Web existantes. Tout ce que Chrome fait est de séparer plusieurs composants (différents onglets, plug-ins, etc.) dans des processus distincts, mais je ne peux pas imaginer une seule page ayant plus d'un thread JavaScript.
Vous pouvez toutefois utiliser, comme cela a été suggéré, setTimeout
pour autoriser une sorte de planification et de concurrence simultanée «fausse». Le navigateur reprend ainsi le contrôle du thread de rendu et démarre le code JavaScript fourni setTimeout
après le nombre de millisecondes donné. Ceci est très utile si vous souhaitez autoriser la fenêtre (ce que vous voyez) à actualiser tout en effectuant des opérations dessus. Le simple fait de parcourir les coordonnées et de mettre à jour un élément en conséquence vous permettra simplement de voir les positions de début et de fin, et rien entre les deux.
Nous utilisons une bibliothèque d'abstraction en JavaScript qui nous permet de créer des processus et des threads qui sont tous gérés par le même interpréteur JavaScript. Cela nous permet d'exécuter des actions de la manière suivante:
Cela permet une certaine forme de planification et un faux parallélisme, le démarrage et l'arrêt des threads, etc., mais ce ne sera pas un vrai multi-threading. Je ne pense pas qu'il sera jamais implémenté dans la langue elle-même, car le vrai multi-thread n'est utile que si le navigateur peut exécuter une seule page multi-thread (ou même plus d'un noyau), et les difficultés y sont beaucoup plus grandes que les possibilités supplémentaires.
Pour l'avenir de JavaScript, consultez ceci: https://developer.mozilla.org/presentations/xtech2006/javascript/
Le multi-threading JavaScript (avec certaines limitations) est ici. Google a implémenté des employés pour Gears, et les employés sont inclus avec HTML5. La plupart des navigateurs ont déjà ajouté la prise en charge de cette fonctionnalité.
La sécurité des threads des données est garantie car toutes les données communiquées à / du travailleur sont sérialisées / copiées.
Pour plus d'informations, lisez:
Traditionnellement, JS était destiné à des morceaux de code courts et rapides. Si vous aviez des calculs majeurs en cours, vous l' avez fait sur un serveur - l'idée d'un JS + HTML app qui ont fonctionné dans votre navigateur pendant de longues périodes de temps à faire des choses non-triviales était absurde.
Bien sûr, nous avons maintenant cela. Mais il faudra un peu de temps aux navigateurs pour rattraper leur retard - la plupart d'entre eux ont été conçus autour d'un modèle à un seul thread, et changer ce n'est pas facile. Google Gears contourne de nombreux problèmes potentiels en exigeant que l'exécution en arrière-plan soit isolée - pas de changement du DOM (car ce n'est pas sûr pour les threads), pas d'accès aux objets créés par le thread principal (idem). Bien que restrictif, ce sera probablement la conception la plus pratique pour un avenir proche, à la fois parce qu'elle simplifie la conception du navigateur et parce qu'elle réduit le risque de permettre aux codeurs JS inexpérimentés de jouer avec les threads ...
@marcio :
Pourquoi est-ce une raison pour ne pas implémenter le multi-threading en Javascript? Les programmeurs peuvent faire ce qu'ils veulent avec les outils dont ils disposent.
Alors, ne leur donnons pas des outils qui sont si faciles à utiliser à mauvais escient que tous les autres sites Web que j'ouvre finissent par planter mon navigateur. Une implémentation naïve de cela vous amènerait directement dans le territoire qui a causé tant de maux de tête à MS pendant le développement d'IE7: les auteurs de modules complémentaires ont joué rapidement et avec le modèle de thread, entraînant des bogues cachés qui sont devenus évidents lorsque les cycles de vie des objets ont changé sur le thread principal . MAUVAIS. Si vous écrivez des modules complémentaires ActiveX multi-thread pour IE, je suppose que cela vient avec le territoire; ne signifie pas qu'il doit aller plus loin que cela.
Je ne connais pas la justification de cette décision, mais je sais que vous pouvez simuler certains des avantages de la programmation multithread en utilisant setTimeout. Vous pouvez donner l'illusion de plusieurs processus faisant les choses en même temps, bien qu'en réalité, tout se passe dans un seul fil.
Demandez à votre fonction de faire un peu de travail, puis appelez quelque chose comme:
setTimeout(function () {
... do the rest of the work...
}, 0);
Et toutes les autres choses à faire (comme les mises à jour de l'interface utilisateur, les images animées, etc.) se produiront lorsqu'elles en auront l'occasion.
loop
intérieur setTimeout
mais apparemment cela ne fonctionne pas. Avez-vous fait quelque chose comme ça ou avez-vous un hack? un exemple serait pour le tableau de 1000 éléments, je m'attends à en utiliser deux pour les boucles à l'intérieur de deux setTimeout
appels de telle sorte que le premier boucle à travers et élément d'impression 0..499
, le second boucle à travers et élément d'impression 500..999
.
Voulez-vous dire pourquoi le langage ne prend-il pas en charge le multithreading ou pourquoi les moteurs JavaScript dans les navigateurs ne prennent-ils pas en charge le multithreading?
La réponse à la première question est que JavaScript dans le navigateur est destiné à être exécuté dans un bac à sable et d'une manière indépendante de la machine / du système d'exploitation, ajouter un support multithreading compliquerait la langue et lierait la langue trop étroitement au système d'exploitation.
Node.js 10.5+ prend en charge les threads de travail comme fonctionnalité expérimentale (vous pouvez l'utiliser avec l' indicateur --experimental-worker activé): https://nodejs.org/api/worker_threads.html
Donc, la règle est:
Les threads de travail sont destinés à être des threads à longue durée de vie, ce qui signifie que vous générez un thread d'arrière-plan, puis vous communiquez avec lui via le passage de messages.
Sinon, si vous devez exécuter une lourde charge CPU avec une fonction anonyme, vous pouvez utiliser https://github.com/wilk/microjob , une petite bibliothèque construite autour de threads de travail.
Comme Matt B l'a dit, la question n'est pas très claire. En supposant que vous posez des questions sur la prise en charge du multithreading dans la langue: car elle n'est pas nécessaire pour 99,999% des applications en cours d'exécution dans le navigateur actuellement. Si vous en avez vraiment besoin, il existe des solutions de contournement (comme l'utilisation de window.setTimeout).
En général, le multithreading est très, très, très, très, très, très difficile (ai-je dit que c'est difficile?) De bien faire les choses, sauf si vous introduisez des restrictions supplémentaires (comme utiliser uniquement des données immuables).
Intel a fait des recherches open source sur le multithreading en Javascript, il a été présenté récemment sur GDC 2012. Voici le lien pour la vidéo . Le groupe de recherche a utilisé OpenCL qui se concentre principalement sur les jeux de puces Intel et le système d'exploitation Windows. Le projet est nommé RiverTrail et le code est disponible sur GitHub
Quelques liens plus utiles:
Construire une autoroute informatique pour les applications Web
Actuellement, certains navigateurs prennent en charge le multithreading. Donc, si vous en avez besoin, vous pouvez utiliser des bibliothèques spécifiques. Par exemple, consultez les documents suivants:
https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers (support des threads d'arrière-plan);
https://keithwhor.github.io/multithread.js/ (la bibliothèque).
Ce sont les implémentations qui ne prennent pas en charge le multithread. Actuellement, Google Gears fournit un moyen d'utiliser une certaine forme de concurrence en exécutant des processus externes, mais c'est à peu près tout.
Le nouveau navigateur que Google est censé publier aujourd'hui (Google Chrome) exécute du code en parallèle en le séparant en cours.
Le langage de base, bien sûr, peut avoir le même support que, disons Java, mais le support de quelque chose comme la concurrence d'Erlang est loin d'être à l'horizon.
Javascript est une langue à fil unique. Cela signifie qu'il a une pile d'appels et un tas de mémoire. Comme prévu, il exécute le code dans l'ordre et doit terminer l'exécution d'un code pièce avant de passer au suivant. C'est synchrone, mais cela peut parfois être dangereux. Par exemple, si une fonction met un certain temps à s'exécuter ou doit attendre quelque chose, elle gèle tout en attendant.
Sans prise en charge linguistique appropriée pour la synchronisation des threads, il n'est même pas logique que de nouvelles implémentations essaient. Les applications JS complexes existantes (par exemple, tout ce qui utilise ExtJS) se bloqueraient très probablement de manière inattendue, mais sans synchronized
mot - clé ou quelque chose de similaire, il serait également très difficile, voire impossible, d'écrire de nouveaux programmes qui se comportent correctement.
Cependant, vous pouvez utiliser la fonction eval pour amener la concurrence à un certain degré
/* content of the threads to be run */
var threads = [
[
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');"
],
[
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');"
]
];
window.onload = function() {
var lines = 0, quantum = 3, max = 0;
/* get the longer thread length */
for(var i=0; i<threads.length; i++) {
if(max < threads[i].length) {
max = threads[i].length;
}
}
/* execute them */
while(lines < max) {
for(var i=0; i<threads.length; i++) {
for(var j = lines; j < threads[i].length && j < (lines + quantum); j++) {
eval(threads[i][j]);
}
}
lines += quantum;
}
}
Le multi-threading avec javascript est clairement possible en utilisant des webworkers apportés par HTML5.
La principale différence entre les travailleurs Web et un environnement multi-threading standard est que les ressources mémoire ne sont pas partagées avec le thread principal, une référence à un objet n'est pas visible d'un thread à l'autre. Les threads communiquent en échangeant des messages, il est donc possible de mettre en œuvre un algorithme de synchronisation et d'appel de méthode simultanée suivant un modèle de conception piloté par les événements.
Il existe de nombreux frameworks permettant de structurer la programmation entre les threads, parmi eux OODK-JS, un framework OOP js supportant la programmation simultanée https://github.com/GOMServices/oodk-js-oop-for-js