Wielowątkowość JavaScript

Pracuję nad porównaniem kilku różnych metod implementacji (prawdziwej lub fałszywej) wielowątkowości w JavaScript. Z tego co wiem tylko webworkerzy i Google Gears WorkerPool mogą dać ci prawdziwe wątki (tj. rozłożone na wiele procesorów z rzeczywistym wykonaniem równoległym). Znalazłem następujące metody:

  • Przełączanie między zadaniami za pomocą yield()

  • Użyj setInterval() (lub innej nieblokującej funkcji) z wątkami czekającymi na another

  • Użyj wątków Google Gears WorkerPool (z wtyczką)

  • Użyj pracowników sieci html5

Czytałem podobne pytania i znalazłem kilka odmian powyższych metod, ale większość z tych pytań jest stara, więc może być kilka nowych pomysłów.

Zastanawiam się - jak inaczej można osiągnąć wielowątkowość w JavaScript? Jakieś inne ważne metody?

UPDATE: jak zaznaczono w komentarzach, tak naprawdę chodziło mi o współbieżność.

Aktualizacja 2: znalazłem informację, że Silverlight + JScript obsługuje wielowątkowość, ale nie jestem w stanie tego zweryfikować.

UPDATE 3: Google deprecated Gears: http://code.google.com/apis/gears/api_workerpool.html

Author: Chris Hasiński, 2011-10-03

5 answers

Web Workers . Są standardem W3C (cóż, roboczy szkic w tej chwili) do tego i nie wymagają żadnych wtyczek: {]}

Ta specyfikacja definiuje API, które umożliwia autorom aplikacji internetowych odradzanie pracowników pracujących w tle, uruchamiających Skrypty równolegle do ich strony głównej.

Specyfikacja omawia również rozsiewanie pracowników na wiele rdzeni, dla prawdziwej współbieżności (jest to obsługiwane niewidocznie przez silnik JavaScript przeglądarki):

Z procesory wielordzeniowe stają się powszechne, jednym ze sposobów na uzyskanie lepszej wydajności jest podział kosztownych obliczeniowo zadań między wielu pracowników. W [jednym] przykładzie kosztowne obliczeniowo zadanie, które ma być wykonane dla każdej liczby od 1 do 10 000 000, jest wyhodowane do dziesięciu podwładnych.

yield() i setInterval() tylko zaplanować rzeczy, które mają się wydarzyć później, nie działają jednocześnie z niczym innym.

 25
Author: s4y,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-17 05:27:07

Zastanawiam się - jak inaczej można osiągnąć wielowątkowość w JavaScript? Jakieś inne ważne metody?

Możesz przekształcić swój kod w kod JavaScript, który nie ma żadnych jawnych pętli ani bezpośrednich wywołań funkcji, zamiast tego kod jest podzielony na małe jednostki wykonania, które są zarządzane przez silnik wątków. W moim przykładowym kodzie pokazuję jak funkcja z pętlami byłaby przekształcana, ale pominąłem mechanizm wywoływania funkcji tylko po to, aby zachować przykład prosty.

Proces transformacji zasadniczo działa przez dzielenie kodu w punktach podziału. Te punkty podziału są wywołaniami funkcji i pętlami (jak pokazano powyżej). W przykładzie użyłem obiektów i kluczy, ale może być znacznie łatwiejsze w silnikach JavaScript przeglądarki, jeśli jednostki przechowują stos jako zmienną obiektową (tzn. przechowują za pomocą this.foo = bar zamiast stack["foo"] = bar).

Na przykład następujący kod:

// Phoney method purely to demonstrate structure
function Foo() {
  var i,
      sum = 0,
      accumulator_list = [],
      accumulator_modulus = [],
      kMaxAccumulatorCount = 100;

  // Calculate accumulations
  for(i = 0; i < kMaxAccumulatorCount; ++i) {
    current_accumulator = GetNextAccumulator()
    accumulator_list[i] = current_accumulator;
    sum = sum + current_accumulator;
  }

  // Calculate accumulator modulus
  for(i = 0; i < kMaxAccumulatorCount; ++i) {
    current_accumulator = accumulator_list[i];
    accumulator_modulus[i] = current_accumulator % kMaxAccumulatorCount;
  }
}

... do coś takiego:

function Foo_A(caller,stack) {
  var stack = {};
  stack["i"] = undefined;
  stack["sum"] = 0;
  stack["accumulator_list"] = [];
  stack["accumulator_modulus"] = [];
  stack["kMaxAccumulatorCount"] = 100;

  stack["i"] = 0;
  return {caller: caller, stack: stack, next=Foo_B};
}

function Foo_B(caller, stack) {
  stack["current_accumulator"] = GetNextAccumulator();
  stack["accumulator_list"][stack["i"]] = stack["current_accumulator"];
  stack["sum"] = stack["sum"] + stack["current_accumulator"];

  // For-loop condition satisfied ?
  if(stack["i"] < stack["kMaxAccumulatorCount"]) {
    ++stack["i"];
    return {caller: caller, stack: stack, next:Foo_B};
  } else {
    // Initialise the next for loop.
    stack["i"] = 0;
    return {caller: caller, stack: stack, next:Foo_C};
  }
}

function Foo_C(caller, stack) {
  stack["current_accumulator"] = stack["current_accumulator"][stack["i"]];
  stack["accumulator_modulus"][stack["i"]] = stack["current_accumulator"] % stack["kMaxAccumulatorCount"];

  // For-loop condition satisfied ?
  if(stack["i"] < stack["kMaxAccumulatorCount"]) {
    ++stack["i"];
    return {caller: caller, stack: stack, next:Foo_C};
  } else {
    // Function has finished so the next will be null. When the thread-engine sees this it simulates the behaviour of a return, pops its virtual stack and returns execution to the caller
    return {caller: caller, stack: stack, next:null};
  }
}
 4
Author: Keldon Alleyne,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-27 08:34:50

Multithread.js jest biblioteką do naprawdę łatwego wielowątkowości w JS, która owija pracowników sieci i wykonuje większość twojej pracy za Ciebie. :)

 3
Author: kwh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-28 14:47:23

Nie ma bezpośredniego wsparcia dla wielowątkowości w JavaScript. Jednak można to osiągnąć, stosując kilka pomysłów i metod.

Istnieją metody takie jak:

var id = window.timeout("javascript code", time);

Tutaj kod JavaScript jest wywoływany po określonym czasie i możemy użyć

window.clearTimeout(id);

Do oczyszczenia. Dzięki temu możemy osiągnąć fałszywą współbieżność.

 2
Author: Chris Hasiński,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-20 14:40:16

Q: jak inaczej można osiągnąć współbieżność w Javascript

Możesz używać metod typu async lub 'non-blocking'. To ma jeden z głównych brzęczy o węźle.js system. Nie jest do końca wielowątkowy, ale zazwyczaj jest szybszy.

 1
Author: BenG,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-07 00:16:47