Warum unterstützt JavaScript Multithreading nicht?

269

Ist es eine bewusste Designentscheidung oder ein Problem mit unseren aktuellen Browsern, das in den kommenden Versionen behoben wird?

Niyaz
quelle
3
Informationen zu Web Workern / Worker-Threads finden Sie auch in den Antworten auf die Frage zu JavaScript und Threads .
Sam Hasler
115
Hallo Googler. Sie werden vielleicht bemerken, dass hier alles ziemlich veraltet zu sein scheint (beachten Sie, dass diese Frage vor über 5 Jahren gestellt wurde). Seitdem sie gestellt wurde, haben Webbrowser einige Funktionen erhalten, die, soweit ich das beurteilen kann, mehr oder weniger Multithreading sind. Werfen
ArtOfWarfare
2
Multithread.js umschließt Web Worker und ermöglicht einfaches Multithreading in JS. Funktioniert mit allen neuen Browsern, einschließlich iOS Safari. :)
kwh
1
Mögliches Duplikat von JavaScript und Threads
Matt

Antworten:

194

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, setTimeouteine Art Zeitplanung und "falsche" Parallelität zulassen. Dadurch setTimeouterhä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:

  • Prozess A, Thread 1
  • Prozess A, Thread 2
  • Prozess B, Thread 1
  • Prozess A, Thread 3
  • Prozess A, Thread 4
  • Prozess B, Thread 2
  • Prozess A anhalten
  • Prozess B, Thread 3
  • Prozess B, Thread 4
  • Prozess B, Thread 5
  • Prozess A starten
  • Prozess A, Thread 5

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/

Kamiel Wanrooij
quelle
73
Ich denke, nie umgesetzt ist eine zu enge Vision. Ich garantiere, dass Web-Apps irgendwann wirklich Multithreading-fähig sein werden (dies ist nur logisch, da Web-Apps dominanter werden und Hardware paralleler wird), und wie ich sehe, ist JavaScript die De-facto-Sprache der Webentwicklung muss irgendwann Multithreading unterstützen oder durch etwas ersetzt werden, das dies tut.
devios1
6
Nie ist wahrscheinlich eine etwas zu kühne Aussage :), aber ich denke immer noch, dass die Vorteile von echtem Multithread-Javascript auf absehbare Zeit nicht realisierbar sind;)
Kamiel Wanrooij
5
Obwohl ich argumentieren würde, dass Web-Worker durch ein Prozessmodell mehr gleichzeitig als durch ein Thread-Modell sind. Web-Worker verwenden die Nachrichtenübermittlung als Kommunikationsmittel. Dies ist eine elegante Lösung für die "üblichen" Parallelitätsprobleme in Multithread-Anwendungen. Ich bin nicht sicher, ob sie tatsächlich gleichzeitig mit denselben Objekten wie die Hauptseite arbeiten können. Sie können meines Wissens nicht auf das DOM zugreifen. Das meiste davon ist jedoch semantisch, Web-Worker sehen in jeder Hinsicht vielversprechend aus.
Kamiel Wanrooij
Schwierigkeiten gibt es viel größer als die zusätzlichen Möglichkeiten Ich bin mir nicht sicher, ob Sie an all die zusätzlichen Möglichkeiten denken. Ich denke insbesondere an Fälle, in denen Webgl wie in Spielen oder grafischen Visualisierungen verwendet wird. Betrachten Sie beispielsweise die neue 3D-Version von Google Maps. In Städten mit vielen 3D-Modellen benötigt mein PC ~ 2 Minuten, um alles zu laden, wenn viele Häuser gerendert werden müssen. In bestimmten Winkeln sind weder meine Grafikkarte noch mein Netzwerk voll ausgelastet. Aber 1 von 8 Prozessoren ist zu 100%. Multithreading ist auch ein großes
Problem
25

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:

http://www.whatwg.org/specs/web-workers/current-work/

http://ejohn.org/blog/web-workers/

Neil
quelle
8
Aber ist es nicht eher ein Multiprozess-Ansatz als ein Multithread-Ansatz? Es ist bekannt, dass Threads innerhalb eines einzelnen Heaps funktionieren.
Beefeather
1
@beefeather, das stimmt. Es ist eher ein Prozessansatz.
Neil
23

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.

Shog9
quelle
6
"Es verringert das Risiko, unerfahrene JS-Codierer mit Threads herumspielen zu lassen." Warum ist dies ein Grund, Multithreading nicht in Javascript zu implementieren? Programmierer können mit ihren Werkzeugen machen, was sie wollen. Wenn es gut oder schlecht ist, ist es ihr Problem. Mit dem Google Chrome-Prozessmodell können nicht einmal andere Anwendungen beeinflusst werden. :)
Marcio Aguiar
3
@ Shog9 - "Geben wir [Programmierern] keine Tools, die so leicht zu missbrauchen sind, dass jede andere Website, die ich öffne, meinen Browser zum Absturz bringt." - Was? Nach derselben Logik sollte keine Sprache Multithreading haben, denn wenn sie anbieten würde, dass jedes andere Programm, das Sie öffnen wollten, abstürzt. Nur dass es so nicht funktioniert. Threading gibt es in den meisten Sprachen, und die meisten Programmieranfänger berühren es nicht, und die meisten, die es nicht in Produktion bringen, und die Apps, die niemals populär oder weit verbreitet werden.
ArtOfWarfare
11

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.

pkaeding
quelle
In den meisten Fällen würde ich gerne ein loopInside verwenden, setTimeoutaber 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 setTimeoutAufrufen zu verwenden, sodass die erste Schleife durch und das Druckelement 0..499, die zweite Schleife durch und das Druckelement 500..999.
Benjamin
Normalerweise besteht die Technik darin, den Zustand zu speichern und fortzufahren. Angenommen, Sie möchten 0 bis 1000 drucken, dann können Sie 0 bis 499 drucken und dann den Trick setTimeout mit dem Argument 500 ausführen. Der darin enthaltene Code würde das Argument (500) verwenden und die Schleife von dort aus starten.
Eyal
8

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.

matt b
quelle
6

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:

  • Wenn Sie E / A-gebundene Operationen ausführen müssen , verwenden Sie den internen Mechanismus (auch bekannt als Rückruf / Versprechen / Async-Warten).
  • Wenn Sie CPU-gebundene Operationen ausführen müssen , verwenden Sie Arbeitsthreads.

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.

Wilk
quelle
4

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).

Grauer Panther
quelle
3

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:

Erstellen einer Computerautobahn für Webanwendungen

Rohit Reddy Korrapolu
quelle
1

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.

Greg Roberts
quelle
1

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.

Omar bakhsh
quelle
0

Soweit ich gehört habe, wird Google Chrome über Multithread-Javascript verfügen, sodass es sich um ein Problem mit "aktuellen Implementierungen" handelt.

BlaM
quelle
0

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 synchronizedSchlüsselwort oder ähnliches wäre es auch sehr schwierig oder sogar unmöglich, neue Programme zu schreiben, die sich korrekt verhalten.

Erich Kitzmüller
quelle
-1

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;
    }
}
Madhusoodan P.
quelle
-2

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

OBDM
quelle
5
Die gemeinsame Nutzung von Speicher ist die genaue Definition eines Threads im Gegensatz zu einem separaten Prozess (z. B. fork () vs exec ()). Threads können Objekte gemeinsam nutzen, Prozesse müssen IPC verwenden. Web Worker sind kein Multithreading.
Felixfbecker