È una decisione di progettazione deliberata o un problema con i nostri browser attuali che verranno corretti nelle prossime versioni?
È una decisione di progettazione deliberata o un problema con i nostri browser attuali che verranno corretti nelle prossime versioni?
Risposte:
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, setTimeout
per 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 setTimeout
dopo 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:
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/
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:
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.
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à.
loop
interno setTimeout
ma 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 setTimeout
chiamate in modo tale che il primo passi attraverso e stampi l'elemento 0..499
, il secondo passi attraverso e stampi l'elemento 500..999
.
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.
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 è:
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.
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).
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:
Attualmente alcuni browser supportano il multithreading. Quindi, se necessario, è possibile utilizzare librerie specifiche. Ad esempio, visualizza i materiali seguenti:
https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers (supporto thread di sfondo);
https://keithwhor.github.io/multithread.js/ (la libreria).
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.
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.
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 synchronized
parola chiave o qualcosa di simile, sarebbe anche molto difficile o addirittura impossibile scrivere nuovi programmi che si comportano correttamente.
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;
}
}
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