Czy jest to celowa decyzja projektowa czy problem z naszymi przeglądarkami na dzień dzisiejszy, który zostanie naprawiony w nadchodzących wersjach?
Czy jest to celowa decyzja projektowa czy problem z naszymi przeglądarkami na dzień dzisiejszy, który zostanie naprawiony w nadchodzących wersjach?
Odpowiedzi:
JavaScript nie obsługuje wielowątkowości, ponieważ interpreter JavaScript w przeglądarce jest jednym wątkiem (AFAIK). Nawet Google Chrome nie pozwala na równoczesne działanie kodu JavaScript pojedynczej strony internetowej, ponieważ spowodowałoby to poważne problemy z współbieżnością na istniejących stronach internetowych. Wszystko, co robi Chrome, to oddzielne wiele komponentów (różne karty, wtyczki itp.) W osobne procesy, ale nie wyobrażam sobie, żeby jedna strona miała więcej niż jeden wątek JavaScript.
Możesz jednak użyć, jak sugerowano, setTimeout
aby zezwolić na pewnego rodzaju planowanie i „fałszywą” współbieżność. Powoduje to, że przeglądarka odzyskuje kontrolę nad wątkiem renderującym i uruchamia dostarczony kod JavaScript setTimeout
po upływie określonej liczby milisekund. Jest to bardzo przydatne, jeśli chcesz umożliwić odświeżanie okienka ekranu (tego, co widzisz) podczas wykonywania na nim operacji. Samo zapętlenie np. Współrzędnych i odpowiednia aktualizacja elementu pozwoli ci zobaczyć pozycje początkową i końcową, i nic pomiędzy.
W JavaScript używamy biblioteki abstrakcji, która pozwala nam tworzyć procesy i wątki, którymi zarządza ten sam interpreter JavaScript. To pozwala nam uruchamiać działania w następujący sposób:
Pozwala to na pewną formę planowania i podobieństwa równoległości, uruchamiania i zatrzymywania wątków itp., Ale nie będzie to prawdziwa wielowątkowość. Nie sądzę, aby kiedykolwiek został zaimplementowany w samym języku, ponieważ prawdziwa wielowątkowość jest przydatna tylko wtedy, gdy przeglądarka może uruchomić wielowątkową stronę (lub nawet więcej niż jeden rdzeń), a trudności są znacznie większe niż dodatkowe możliwości.
Jeśli chodzi o przyszłość JavaScript, sprawdź to: https://developer.mozilla.org/presentations/xtech2006/javascript/
JavaScript wielowątkowość (z pewnymi ograniczeniami) jest tutaj. Google zaimplementował pracowników dla Gears, a pracownicy są dołączani do HTML5. Większość przeglądarek już dodała obsługę tej funkcji.
Bezpieczeństwo wątków danych jest gwarantowane, ponieważ wszystkie dane przekazywane do / od pracownika są serializowane / kopiowane.
Aby uzyskać więcej informacji, przeczytaj:
Tradycyjnie JS był przeznaczony do krótkich, szybko działających fragmentów kodu. Jeśli miałeś poważne obliczenia, zrobiłeś to na serwerze - pomysł aplikacji JS + HTML, która działała w przeglądarce przez długi czas, robiąc rzeczy niebanalne, był absurdalny.
Oczywiście teraz to mamy. Ale przeglądarka zajmie trochę czasu - większość z nich została zaprojektowana w oparciu o model jednowątkowy, a zmiana nie jest łatwa. Google Gears omija wiele potencjalnych problemów, wymagając, aby wykonanie w tle było izolowane - bez zmiany DOM (ponieważ nie jest to bezpieczne dla wątków), bez dostępu do obiektów utworzonych przez główny wątek (to samo). Chociaż jest to restrykcyjne, będzie to prawdopodobnie najbardziej praktyczny projekt w najbliższej przyszłości, zarówno dlatego, że upraszcza projektowanie przeglądarki, jak i ponieważ zmniejsza ryzyko związane z umożliwieniem niedoświadczonym programistom JS bałagania się z wątkami ...
@marcio :
Dlaczego jest to powód, aby nie wdrażać wielowątkowości w JavaScript? Programiści mogą robić, co chcą, korzystając z posiadanych narzędzi.
Więc nie dawajmy im narzędzi, które są tak łatwe do niewłaściwego użycia, że każda inna strona, którą otwieram, powoduje awarię mojej przeglądarki. Naiwna implementacja tego przyniosłaby cię prosto na terytorium, które spowodowało wiele bólów głowy podczas rozwoju IE7: autorzy dodatków grali szybko i luźno z modelem wątków, powodując ukryte błędy, które stały się widoczne, gdy cykle życia obiektu zmieniły się w głównym wątku . ZŁY. Jeśli piszesz wielowątkowe dodatki ActiveX dla IE, myślę, że pochodzi z terytorium; nie znaczy, że musi iść dalej.
Nie znam uzasadnienia tej decyzji, ale wiem, że możesz symulować niektóre korzyści programowania wielowątkowego za pomocą setTimeout. Możesz złudzić, że wiele procesów robi to w tym samym czasie, chociaż w rzeczywistości wszystko dzieje się w jednym wątku.
Niech twoja funkcja wykona trochę pracy, a następnie wywoła coś takiego:
setTimeout(function () {
... do the rest of the work...
}, 0);
I wszelkie inne rzeczy, które należy zrobić (takie jak aktualizacje interfejsu użytkownika, animowane obrazy itp.) Zdarzają się, gdy mają szansę.
loop
wewnątrz, setTimeout
ale najwyraźniej to nie działa. Czy zrobiłeś coś takiego lub masz hack? przykładem może być tablica 1000 elementów, spodziewam się użyć dwóch pętli dla dwóch setTimeout
wywołań, tak że pierwsza pętla przechodzi przez element print 0..499
, druga pętla przechodzi przez element print 500..999
.
Czy masz na myśli, dlaczego język nie obsługuje wielowątkowości lub dlaczego silniki JavaScript w przeglądarkach nie obsługują wielowątkowości?
Odpowiedź na pierwsze pytanie jest taka, że JavaScript w przeglądarce ma być uruchamiany w piaskownicy oraz w sposób niezależny od maszyny / systemu operacyjnego, dodanie obsługi wielowątkowości skomplikowałoby język i zbytnio wiązało język z systemem operacyjnym.
Node.js 10.5+ obsługuje wątki robocze jako funkcję eksperymentalną (można go używać z włączoną opcją --experimental-worker ): https://nodejs.org/api/worker_threads.html
Tak więc reguła jest następująca:
Wątki robocze mają być wątkami długowiecznymi, co oznacza, że odradzasz wątek tła, a następnie komunikujesz się z nim poprzez przekazywanie wiadomości.
W przeciwnym razie, jeśli chcesz wykonać duże obciążenie procesora za pomocą anonimowej funkcji, możesz przejść do https://github.com/wilk/microjob , niewielkiej biblioteki zbudowanej wokół wątków roboczych.
Tak jak powiedział Matt B, pytanie nie jest bardzo jasne. Zakładając, że pytasz o obsługę wielowątkowości w języku: ponieważ nie jest ona potrzebna dla 99,999% aplikacji działających obecnie w przeglądarce. Jeśli naprawdę tego potrzebujesz, istnieją obejścia (na przykład użycie window.setTimeout).
Ogólnie rzecz biorąc, wielowątkowość jest bardzo, bardzo, bardzo, bardzo, bardzo, bardzo trudna (czy powiedziałem, że jest to trudne?), Jeśli nie wprowadzisz dodatkowych ograniczeń (takich jak używanie tylko niezmiennych danych).
Intel przeprowadził pewne badania open source dotyczące wielowątkowości w Javascripcie, które niedawno zaprezentowano na GDC 2012. Oto link do filmu . Grupa badawcza wykorzystała OpenCL, który koncentruje się głównie na zestawach układów Intel i systemie operacyjnym Windows. Projekt nosi nazwę RiverTrail, a kod jest dostępny na GitHub
Niektóre bardziej przydatne linki:
Obecnie niektóre przeglądarki obsługują wielowątkowość. Więc jeśli potrzebujesz, możesz użyć określonych bibliotek. Na przykład zobacz następne materiały:
https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers (obsługa wątków w tle);
https://keithwhor.github.io/multithread.js/ (biblioteka).
To implementacje, które nie obsługują wielowątkowości. Obecnie Google Gears zapewnia sposób korzystania z pewnej formy współbieżności poprzez wykonywanie zewnętrznych procesów, ale o to chodzi.
Nowa przeglądarka, którą Google ma dziś wypuścić (Google Chrome), wykonuje równolegle jakiś kod, oddzielając go w procesie.
Język podstawowy może oczywiście mieć taką samą obsługę jak, powiedzmy Java, ale obsługa czegoś takiego jak współbieżność Erlanga nie jest nigdzie w pobliżu.
JavaScript jest językiem jednowątkowym. Oznacza to, że ma jeden stos wywołań i jeden stos pamięci. Zgodnie z oczekiwaniami wykonuje kod w kolejności i musi zakończyć wykonywanie kodu części przed przejściem do następnego. Jest synchroniczny, ale czasami może być szkodliwy. Na przykład, jeśli funkcja wymaga czasu na wykonanie lub musi na coś poczekać, w międzyczasie zawiesza wszystko.
Bez odpowiedniego wsparcia językowego do synchronizacji wątków nawet nowe implementacje nie mają sensu. Istniejące złożone aplikacje JS (np. Wszystko korzystające z ExtJS) najprawdopodobniej uległyby awarii nieoczekiwanie, ale bez synchronized
słowa kluczowego lub czegoś podobnego bardzo trudno byłoby nawet napisać nowe programy, które zachowują się poprawnie.
Możesz jednak użyć funkcji eval, aby wprowadzić współbieżność W NIEKTÓRY ZAKRES
/* 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;
}
}
Wielowątkowość z javascript jest oczywiście możliwa przy użyciu webworkerów wprowadzonych przez HTML5.
Główną różnicą między pracownikami sieci a standardowym środowiskiem wielowątkowym jest to, że zasoby pamięci nie są współużytkowane z głównym wątkiem, odniesienie do obiektu nie jest widoczne z jednego wątku do drugiego. Wątki komunikują się poprzez wymianę komunikatów, dlatego możliwe jest wdrożenie algorytmu synchronizacji i współbieżnego wywołania metody zgodnie ze wzorcem projektowym sterowanym zdarzeniami.
Istnieje wiele struktur umożliwiających strukturę programowania między wątkami, w tym OODK-JS, platforma OOP js wspierająca programowanie współbieżne https://github.com/GOMServices/oodk-js-oop-for-js