Perché JavaScript non supporta il multithreading?


269

È una decisione di progettazione deliberata o un problema con i nostri browser attuali che verranno corretti nelle prossime versioni?


3
Vedi anche le risposte alla domanda JavaScript e Discussioni per informazioni sui web worker / sui thread di lavoro.
Sam Hasler,

115
Ciao amico Googler. Potresti notare che tutto qui sembra essere piuttosto datato (nota che questa domanda è stata posta oltre 5 anni fa.) Da quando è stata posta, i browser web hanno acquisito alcune funzionalità che, per quanto posso dire, sono più o meno multithreading. Date un'occhiata a lavoratori Web: msdn.microsoft.com/en-us/hh549259.aspx
ArtOfWarfare

2
Multithread.js racchiude Web Worker e consente un facile multithreading in JS. Funziona su tutti i nuovi browser, incluso iOS Safari. :)
kwh

1
Possibile duplicato di JavaScript e discussioni
Matt,

Risposte:


194

JavaScript non supporta il multi-threading perché l'interprete JavaScript nel browser è un thread singolo (AFAIK). Anche Google Chrome non consentirà l'esecuzione simultanea di JavaScript di una singola pagina Web poiché ciò causerebbe enormi problemi di concorrenza nelle pagine Web esistenti. Tutto ciò che fa Chrome è separare più componenti (diverse schede, plug-in, eccetera) in processi separati, ma non riesco a immaginare una singola pagina con più di un thread JavaScript.

Tuttavia, è possibile utilizzare, come è stato suggerito, setTimeoutper consentire una sorta di programmazione e concorrenza "falsa". Questo fa sì che il browser riacquisti il ​​controllo del thread di rendering e avvii il codice JavaScript fornito setTimeoutdopo il dato numero di millisecondi. Ciò è molto utile se si desidera consentire l'aggiornamento del viewport (ciò che si vede) durante l'esecuzione delle operazioni su di esso. Basta scorrere ad esempio le coordinate e aggiornare di conseguenza un elemento per vedere le posizioni di inizio e fine e niente in mezzo.

Usiamo una libreria di astrazione in JavaScript che ci consente di creare processi e thread che sono tutti gestiti dallo stesso interprete JavaScript. Questo ci consente di eseguire azioni nel modo seguente:

  • Processo A, Discussione 1
  • Processo A, Discussione 2
  • Processo B, Discussione 1
  • Processo A, Discussione 3
  • Processo A, Discussione 4
  • Processo B, Discussione 2
  • Sospendi processo A
  • Processo B, Discussione 3
  • Processo B, Discussione 4
  • Processo B, Discussione 5
  • Avvia processo A
  • Processo A, Discussione 5

Ciò consente una qualche forma di programmazione e simula il parallelismo, l'avvio e l'arresto di thread, eccetera, ma non sarà un vero multi-threading. Non penso che sarà mai implementato nella lingua stessa, poiché il vero multi-threading è utile solo se il browser può eseguire una singola pagina multi-thread (o anche più di un core) e le difficoltà che ci sono sono molto più grandi rispetto alle possibilità extra.

Per il futuro di JavaScript, dai un'occhiata a: https://developer.mozilla.org/presentations/xtech2006/javascript/


73
Penso che mai implementato sia una visione troppo ristretta. Garantisco che le app web potranno finalmente essere veramente multithread (è solo logico, poiché le app web diventano più dominanti e l'hardware diventa più parallelo) e, a mio avviso, dal momento che JavaScript è il linguaggio di fatto dello sviluppo web, esso alla fine dovrà supportare il multithreading o essere sostituito da qualcosa che lo fa.
devios1

6
Probabilmente non è mai una frase troppo audace :) ma penso ancora che i vantaggi del vero javascript multithread non siano fattibili in un futuro prevedibile;)
Kamiel Wanrooij,

5
Anche se direi che i lavoratori del web sono più concorrenti attraverso un modello di processo che un modello di thread. Gli operatori Web utilizzano il passaggio dei messaggi come mezzo di comunicazione, che rappresenta una soluzione elegante ai "consueti" problemi di concorrenza nelle applicazioni multithread. Non sono sicuro che possano effettivamente operare contemporaneamente sugli stessi oggetti della pagina principale. Non possono accedere al DOM per quanto ne so. Tuttavia, la maggior parte di questi è semantica, i lavoratori del web sembrano promettenti a tutti gli effetti.
Kamiel Wanrooij,

le difficoltà ci sono molto più grandi delle possibilità extra Non sono sicuro se pensi a tutte le possibilità extra. Sto pensando in particolare ai casi in cui il webgl viene utilizzato come nei giochi o nelle visualizzazioni grafiche. Ad esempio, considera la nuova versione 3D di Google Maps. Nelle città con molti modelli 3D il mio PC ha bisogno di ~ 2 minuti per caricare tutto quando è necessario il rendering di molte case. Ad alcuni angoli né la mia scheda grafica né la mia rete funzionano a pieno regime. Ma 1 su 8 processori è al 100%. Il multithreading è anche una grande preoccupazione in termini di fps, come mostra questo esempio: youtube.com/watch?v=sJ2p982cZFc
Scindix,

25

Il multi-threading JavaScript (con alcune limitazioni) è qui. Google ha implementato i lavoratori per Gears e i lavoratori vengono inclusi in HTML5. La maggior parte dei browser ha già aggiunto il supporto per questa funzione.

La sicurezza dei thread dei dati è garantita perché tutti i dati comunicati al / dal lavoratore sono serializzati / copiati.

Per maggiori informazioni, leggi:

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

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


8
Ma non è più un approccio multi-processo piuttosto che multi-thread? È noto che i thread funzionano all'interno di un singolo heap.
beefeather,

1
@beefeather, è vero. È più un approccio di processo.
Neil,

23

Tradizionalmente, JS era destinato a pezzi di codice brevi e veloci. Se avevi calcoli importanti in corso, l'hai fatto su un server: l'idea di un'app JS + HTML che è stata eseguita nel tuo browser per lunghi periodi di tempo facendo cose non banali era assurda.

Certo, ora ce l'abbiamo. Ma ci vorrà un po 'prima che i browser riescano a recuperare: la maggior parte di essi è stata progettata attorno a un modello a thread singolo e modificarlo non è facile. Google Gears elimina molti potenziali problemi richiedendo che l'esecuzione in background sia isolata: nessuna modifica del DOM (poiché non è thread-safe), nessun accesso agli oggetti creati dal thread principale (idem). Sebbene restrittivo, questo sarà probabilmente il progetto più pratico per il prossimo futuro, sia perché semplifica la progettazione del browser, sia perché riduce il rischio connesso nel consentire ai programmatori JS inesperti di scherzare con i thread ...

@marcio :

Perché è un motivo per non implementare il multi-threading in Javascript? I programmatori possono fare quello che vogliono con gli strumenti che hanno.

Quindi, non diamo loro strumenti che sono così facili da usare in modo improprio che ogni altro sito Web che apro finisce per bloccare il mio browser. Un'implementazione ingenua di questo ti porterebbe direttamente nel territorio che ha causato così tanti mal di testa alla MS durante lo sviluppo di IE7: gli autori add-on hanno giocato in modo rapido e libero con il modello di threading, risultando in bug nascosti che sono diventati evidenti quando i cicli di vita degli oggetti sono cambiati sul thread primario . MALE. Se stai scrivendo componenti aggiuntivi ActiveX multi-thread per IE, immagino che arrivi con il territorio; non significa che debba andare oltre.


6
"riduce il rischio> nel consentire ai programmatori JS inesperti> di scherzare con i thread" Perché è un motivo per non implementare il multi-threading in Javascript? I programmatori possono fare quello che vogliono con gli strumenti che hanno. Se è buono o cattivo, è il loro problema. Con il modello di processo di Google Chrome non può nemmeno influenzare altre applicazioni. :)
Marcio Aguiar,

3
@ Shog9 - "Non diamo a [programmatori] strumenti che sono così facili da usare in modo improprio che ogni altro sito web che apro finisce per bloccare il mio browser." - Che cosa? Secondo la stessa logica, nessuna lingua dovrebbe avere il multithreading, perché se offrissero che ogni altro programma che hai provato ad aprire si arresterebbe in modo anomalo. Solo che non funziona così. Il threading esiste nella maggior parte delle lingue e la maggior parte dei programmatori principianti non lo tocca, e la maggior parte di quelli che non lo mettono in produzione e quelle app che non sono mai diventate popolari o ampiamente utilizzate.
ArtOfWarfare il

11

Non conosco la logica di questa decisione, ma so che puoi simulare alcuni dei vantaggi della programmazione multi-thread usando setTimeout. Puoi dare l'illusione di più processi che fanno le cose allo stesso tempo, anche se in realtà tutto accade in un unico thread.

Chiedi alla tua funzione di svolgere un po 'di lavoro, quindi chiama qualcosa del tipo:

setTimeout(function () {
    ... do the rest of the work...
}, 0);

E qualsiasi altra cosa che deve essere eseguita (come aggiornamenti dell'interfaccia utente, immagini animate, ecc.) Accadrà quando avranno l'opportunità.


La maggior parte dei casi vorrei usare un loopinterno setTimeoutma apparentemente non funziona. Hai fatto qualcosa del genere o hai un hack? un esempio sarebbe per la matrice di 1000 elementi, mi aspetto di usarne due per i cicli all'interno di due setTimeoutchiamate in modo tale che il primo passi attraverso e stampi l'elemento 0..499, il secondo passi attraverso e stampi l'elemento 500..999.
Benjaminz,

Di solito la tecnica è di salvare lo stato e continuare. Ad esempio, supponiamo di voler stampare da 0 a 1000, è possibile stampare da 0 a 499 e quindi eseguire il trucco setTimeout con l'argomento 500. Il codice interno saprebbe prendere l'argomento (500) e iniziare il ciclo da lì.
Eyal,

8

Intendi perché la lingua non supporta il multithreading o perché i motori JavaScript nei browser non supportano il multithreading?

La risposta alla prima domanda è che JavaScript nel browser deve essere eseguito in una sandbox e in modo indipendente dalla macchina / dal sistema operativo, l'aggiunta di un supporto multithreading complicherebbe la lingua e la legerebbe troppo strettamente al sistema operativo.


6

Node.js 10.5+ supporta i thread di lavoro come funzionalità sperimentale (puoi usarlo con l' opzione --experimental-worker flag abilitata): https://nodejs.org/api/worker_threads.html

Quindi, la regola è:

  • se è necessario eseguire operazioni di I / O associate , utilizzare il meccanismo interno (ovvero callback / promise / async-waitit)
  • se è necessario eseguire operazioni associate alla CPU , utilizzare i thread di lavoro.

I thread di lavoro sono intesi come thread di lunga durata, il che significa che si genera un thread in background e quindi si comunica con esso tramite il passaggio di messaggi.

Altrimenti, se devi eseguire un carico pesante della CPU con una funzione anonima, puoi andare con https://github.com/wilk/microjob , una piccola libreria costruita attorno ai thread di lavoro.


4

Proprio come ha detto Matt B, la domanda non è molto chiara. Supponendo che tu stia chiedendo il supporto del multithreading nella lingua: perché non è necessario per il 99,999% delle applicazioni attualmente in esecuzione nel browser. Se ne hai davvero bisogno, ci sono soluzioni alternative (come usare window.setTimeout).

In generale, il multithreading è molto, molto, molto, molto, molto, molto difficile (ho detto che è difficile?) Ottenere il giusto, a meno che non si inseriscano ulteriori restrizioni (come l'utilizzo di soli dati immutabili).


3

Intel ha svolto alcune ricerche open source sul multithreading in Javascript, è stato presentato di recente su GDC 2012. Ecco il link per il video . Il gruppo di ricerca ha utilizzato OpenCL che si concentra principalmente su set di chip Intel e sistema operativo Windows. Il progetto è chiamato in codice RiverTrail e il codice è disponibile su GitHub

Alcuni link più utili:

Costruire un'autostrada informatica per le applicazioni Web



1

Sono le implementazioni che non supportano il multi-threading. Attualmente Google Gears sta fornendo un modo per utilizzare una qualche forma di concorrenza eseguendo processi esterni, ma questo è tutto.

Il nuovo browser che Google dovrebbe rilasciare oggi (Google Chrome) esegue un po 'di codice in parallelo separandolo nel processo.

Il linguaggio principale, ovviamente, può avere lo stesso supporto di, diciamo Java, ma il supporto per qualcosa come la concorrenza di Erlang non è da nessuna parte vicino all'orizzonte.


1

Javascript è un linguaggio a thread singolo. Ciò significa che ha uno stack di chiamate e un heap di memoria. Come previsto, esegue il codice in ordine e deve completare l'esecuzione di un codice pezzo prima di passare al successivo. È sincrono, ma a volte può essere dannoso. Ad esempio, se una funzione impiega un po 'di tempo per essere eseguita o deve attendere qualcosa, nel frattempo congela tutto.


0

Per quanto ho sentito, Google Chrome avrà javascript multithread, quindi è un problema di "attuali implementazioni".


0

Senza un adeguato supporto linguistico per la sincronizzazione dei thread, non ha nemmeno senso provare nuove implementazioni. Le app JS complesse esistenti (ad es. Qualsiasi cosa che utilizza ExtJS) molto probabilmente andrebbero in crash in modo imprevisto, ma senza una synchronizedparola chiave o qualcosa di simile, sarebbe anche molto difficile o addirittura impossibile scrivere nuovi programmi che si comportano correttamente.


-1

Tuttavia, è possibile utilizzare la funzione eval per portare la concorrenza A ALCUNI MOMENTI

/* 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;
    }
}

-2

Il multi-threading con javascript è chiaramente possibile utilizzando i webworker forniti da HTML5.

La principale differenza tra i webworker e un ambiente multi-threading standard è che le risorse di memoria non sono condivise con il thread principale, un riferimento a un oggetto non è visibile da un thread all'altro. I thread comunicano scambiando messaggi, pertanto è possibile implementare un algoritmo di sincronizzazione dei metodi e di sincronizzazione simultanea seguendo uno schema di progettazione basato sugli eventi.

Esistono molti framework che consentono di strutturare la programmazione tra thread, tra cui OODK-JS, un framework OOP js che supporta la programmazione concorrente https://github.com/GOMServices/oodk-js-oop-for-js


5
La condivisione della memoria è l'esatta definizione di un thread opposto a un processo separato (ad esempio fork () vs exec ()). I thread possono condividere oggetti, i processi devono utilizzare IPC. I Web Worker non sono multithreading.
Felixfbecker,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.