Ist es eine bewusste Designentscheidung oder ein Problem mit unseren aktuellen Browsern, das in den kommenden Versionen behoben wird?
Ist es eine bewusste Designentscheidung oder ein Problem mit unseren aktuellen Browsern, das in den kommenden Versionen behoben wird?
Antworten:
JavaScript unterstützt kein Multithreading, da der JavaScript-Interpreter im Browser ein einzelner Thread (AFAIK) ist. Selbst Google Chrome lässt das JavaScript einer einzelnen Webseite nicht gleichzeitig laufen, da dies zu massiven Problemen bei der Parallelität vorhandener Webseiten führen würde. Alles, was Chrome tut, ist, mehrere Komponenten (verschiedene Registerkarten, Plug-Ins usw.) in separate Prozesse zu trennen, aber ich kann mir nicht vorstellen, dass eine einzelne Seite mehr als einen JavaScript-Thread enthält.
Sie können jedoch, wie vorgeschlagen, setTimeout
eine Art Zeitplanung und "falsche" Parallelität zulassen. Dadurch setTimeout
erhält der Browser die Kontrolle über den Rendering-Thread zurück und startet den JavaScript-Code, der nach der angegebenen Anzahl von Millisekunden bereitgestellt wird . Dies ist sehr nützlich, wenn Sie zulassen möchten, dass das Ansichtsfenster (was Sie sehen) aktualisiert wird, während Vorgänge daran ausgeführt werden. Wenn Sie beispielsweise z. B. Koordinaten durchlaufen und ein Element entsprechend aktualisieren, sehen Sie nur die Start- und Endpositionen und nichts dazwischen.
Wir verwenden eine Abstraktionsbibliothek in JavaScript, mit der wir Prozesse und Threads erstellen können, die alle von demselben JavaScript-Interpreter verwaltet werden. Auf diese Weise können wir Aktionen auf folgende Weise ausführen:
Dies ermöglicht eine Form der Planung und fälscht Parallelität, das Starten und Stoppen von Threads usw., aber es wird kein echtes Multithreading sein. Ich denke nicht, dass es jemals in der Sprache selbst implementiert werden wird, da echtes Multithreading nur dann nützlich ist, wenn der Browser eine einzelne Seite mit mehreren Threads (oder sogar mehr als einem Kern) ausführen kann und die Schwierigkeiten dort viel größer sind als die zusätzlichen Möglichkeiten.
Informationen zur Zukunft von JavaScript finden Sie unter: https://developer.mozilla.org/presentations/xtech2006/javascript/
JavaScript-Multithreading (mit einigen Einschränkungen) ist hier. Google hat Worker für Gears implementiert, und Worker werden in HTML5 aufgenommen. Die meisten Browser haben bereits Unterstützung für diese Funktion hinzugefügt.
Die Thread-Sicherheit der Daten ist gewährleistet, da alle dem / vom Mitarbeiter übermittelten Daten serialisiert / kopiert werden.
Weitere Informationen finden Sie unter:
Traditionell war JS für kurze, schnell laufende Codeteile gedacht. Wenn Sie umfangreiche Berechnungen durchgeführt haben, haben Sie dies auf einem Server durchgeführt - die Idee einer JS + HTML- App , die über einen längeren Zeitraum in Ihrem Browser ausgeführt wurde und nicht triviale Aufgaben ausführt, war absurd.
Natürlich haben wir das jetzt. Es wird jedoch einige Zeit dauern, bis die Browser aufholen - die meisten von ihnen wurden um ein Single-Thread-Modell herum entwickelt, und das zu ändern ist nicht einfach. Google Gears umgeht viele potenzielle Probleme, indem es erfordert, dass die Hintergrundausführung isoliert ist - keine Änderung des DOM (da dies nicht threadsicher ist), kein Zugriff auf Objekte, die vom Hauptthread erstellt wurden (dito). Obwohl dies restriktiv ist, wird es wahrscheinlich das praktischste Design für die nahe Zukunft sein, sowohl weil es das Design des Browsers vereinfacht als auch weil es das Risiko verringert, unerfahrene JS-Codierer mit Threads herumspielen zu lassen ...
@ Marcio :
Warum ist das ein Grund, Multithreading nicht in Javascript zu implementieren? Programmierer können mit ihren Werkzeugen machen, was sie wollen.
Geben wir ihnen also keine Tools, die so leicht zu missbrauchen sind, dass jede andere Website, die ich öffne, meinen Browser zum Absturz bringt. Eine naive Implementierung würde Sie direkt in das Gebiet bringen, das MS während der IE7-Entwicklung so viele Kopfschmerzen bereitete: Add-On-Autoren spielten schnell und locker mit dem Threading-Modell, was zu versteckten Fehlern führte, die offensichtlich wurden, wenn sich die Objektlebenszyklen im primären Thread änderten . SCHLECHT. Wenn Sie ActiveX-Add-Ons mit mehreren Threads für den Internet Explorer schreiben, hängt dies vermutlich vom Gebiet ab. bedeutet nicht, dass es noch weiter gehen muss.
Ich kenne die Gründe für diese Entscheidung nicht, aber ich weiß, dass Sie mit setTimeout einige der Vorteile der Multithread-Programmierung simulieren können. Sie können die Illusion vermitteln, dass mehrere Prozesse gleichzeitig ausgeführt werden, obwohl in Wirklichkeit alles in einem Thread geschieht.
Lassen Sie einfach Ihre Funktion ein wenig arbeiten und rufen Sie dann Folgendes auf:
setTimeout(function () {
... do the rest of the work...
}, 0);
Und alle anderen Dinge, die getan werden müssen (wie UI-Updates, animierte Bilder usw.), werden passieren, wenn sie eine Chance bekommen.
loop
Inside verwenden, setTimeout
aber anscheinend funktioniert das nicht. Hast du so etwas gemacht oder hast du einen Hack? Ein Beispiel wäre ein Array mit 1000 Elementen. Ich erwarte, zwei for-Schleifen innerhalb von zwei setTimeout
Aufrufen zu verwenden, sodass die erste Schleife durch und das Druckelement 0..499
, die zweite Schleife durch und das Druckelement 500..999
.
Meinen Sie damit, warum die Sprache Multithreading nicht unterstützt oder warum JavaScript-Engines in Browsern Multithreading nicht unterstützen?
Die Antwort auf die erste Frage lautet, dass JavaScript im Browser in einer Sandbox und auf maschinen- / betriebssystemunabhängige Weise ausgeführt werden soll. Das Hinzufügen von Multithreading-Unterstützung würde die Sprache komplizieren und die Sprache zu eng mit dem Betriebssystem verknüpfen.
Node.js 10.5+ unterstützt Worker-Threads als experimentelle Funktion (Sie können sie mit aktiviertem Flag --experimental-worker verwenden): https://nodejs.org/api/worker_threads.html
Die Regel lautet also:
Worker-Threads sollen langlebige Threads sein, dh Sie erzeugen einen Hintergrund-Thread und kommunizieren dann über die Nachrichtenübermittlung mit ihm.
Wenn Sie andernfalls eine hohe CPU-Auslastung mit einer anonymen Funktion ausführen müssen, können Sie https://github.com/wilk/microjob verwenden , eine winzige Bibliothek, die sich um Arbeitsthreads dreht.
Genau wie Matt B sagte, ist die Frage nicht sehr klar. Angenommen, Sie fragen nach Multithreading-Unterstützung in der Sprache: Weil sie für 99,999% der Anwendungen, die derzeit im Browser ausgeführt werden, nicht benötigt wird. Wenn Sie es wirklich brauchen, gibt es Problemumgehungen (wie die Verwendung von window.setTimeout).
Im Allgemeinen ist Multithreading sehr, sehr, sehr, sehr, sehr, sehr schwer (habe ich gesagt, dass es schwer ist?), Richtig zu werden, es sei denn, Sie haben zusätzliche Einschränkungen eingeführt (z. B. nur unveränderliche Daten zu verwenden).
Intel hat Open-Source-Forschungen zum Thema Multithreading in Javascript durchgeführt. Diese wurden kürzlich auf der GDC 2012 vorgestellt. Hier ist der Link für das Video . Die Forschungsgruppe verwendete OpenCL, das sich hauptsächlich auf Intel-Chipsätze und Windows-Betriebssysteme konzentriert. Das Projekt trägt den Codenamen RiverTrail und der Code ist auf GitHub verfügbar
Einige weitere nützliche Links:
Derzeit unterstützen einige Browser Multithreading. Wenn Sie das brauchen, können Sie bestimmte Bibliotheken verwenden. Sehen Sie sich beispielsweise die nächsten Materialien an:
https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers (Hintergrundthreads unterstützen);
https://keithwhor.github.io/multithread.js/ (die Bibliothek).
Es sind die Implementierungen, die Multithreading nicht unterstützen. Derzeit bietet Google Gears eine Möglichkeit, eine Form der Parallelität zu verwenden, indem externe Prozesse ausgeführt werden.
Der neue Browser, den Google heute veröffentlichen soll (Google Chrome), führt Code parallel aus, indem er ihn in Bearbeitung trennt.
Die Kernsprache kann natürlich die gleiche Unterstützung haben wie beispielsweise Java, aber die Unterstützung für etwas wie Erlangs Parallelität ist bei weitem nicht in Sicht.
Javascript ist eine Single-Threaded-Sprache. Dies bedeutet, dass es einen Aufrufstapel und einen Speicherheap hat. Wie erwartet wird der Code der Reihe nach ausgeführt und die Ausführung eines Stückcodes muss abgeschlossen sein, bevor mit dem nächsten fortgefahren werden kann. Es ist synchron, aber manchmal kann das schädlich sein. Wenn die Ausführung einer Funktion beispielsweise eine Weile dauert oder auf etwas warten muss, friert sie in der Zwischenzeit alles ein.
Ohne die richtige Sprachunterstützung für die Thread-Synchronisation ist es für neue Implementierungen nicht einmal sinnvoll, dies zu versuchen. Bestehende komplexe JS-Apps (z. B. alles, was ExtJS verwendet) würden höchstwahrscheinlich unerwartet abstürzen, aber ohne ein synchronized
Schlüsselwort oder ähnliches wäre es auch sehr schwierig oder sogar unmöglich, neue Programme zu schreiben, die sich korrekt verhalten.
Sie können jedoch die Auswertungsfunktion verwenden, um die Parallelität auf EINIGEN UMFANG zu bringen
/* 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;
}
}
Multithreading mit Javascript ist mit Webworkern von HTML5 eindeutig möglich.
Der Hauptunterschied zwischen Webworkern und einer Standard-Multithreading-Umgebung besteht darin, dass Speicherressourcen nicht mit dem Hauptthread geteilt werden und ein Verweis auf ein Objekt von einem Thread zum anderen nicht sichtbar ist. Threads kommunizieren durch den Austausch von Nachrichten. Daher ist es möglich, einen Synchronisations- und gleichzeitigen Methodenaufrufalgorithmus nach einem ereignisgesteuerten Entwurfsmuster zu implementieren.
Es gibt viele Frameworks, mit denen die Programmierung zwischen Threads strukturiert werden kann, darunter OODK-JS, ein OOP js-Framework, das die gleichzeitige Programmierung unterstützt. Https://github.com/GOMServices/oodk-js-oop-for-js