Многопоточность JavaScript - PullRequest
33 голосов
/ 03 октября 2011

Я работаю над сравнением нескольких различных методов реализации (реального или поддельного) многопоточности в JavaScript.Насколько я знаю, только веб-разработчики и Google Gears WorkerPool могут дать вам реальные потоки (т. Е. Распределенные между несколькими процессорами с реальным параллельным выполнением).Я нашел следующие методы:

  • переключаться между задачами, используя yield()

  • использовать setInterval() (или другие неблокирующие функции) с потоками, ожидающими друг друга

  • использование потоков Google Gears WorkerPool (с плагином)

  • использование веб-работников html5

Я прочитал похожие вопросы и нашел несколько вариантов вышеупомянутых методов, но большинство из этих вопросов старые, поэтому может появиться несколько новых идей.

Мне интересно - как ещевы можете достичь многопоточности в JavaScript?Любые другие важные методы?

ОБНОВЛЕНИЕ: Как указано в комментариях, я действительно имел в виду параллелизм.

ОБНОВЛЕНИЕ 2: Я нашел информацию о том, что Silverlight + JScript поддерживает многопоточность, но я не могу проверить это.

ОБНОВЛЕНИЕ 3: Googleустаревшие Gears: http://code.google.com/apis/gears/api_workerpool.html

Ответы [ 5 ]

25 голосов
/ 07 октября 2011

Web Workers .Это стандарт W3C (ну, на данный момент, рабочий проект) именно для этого и не требует плагинов:

Эта спецификация определяет API, который позволяет авторам веб-приложений порождать фоновых рабочих, выполняющих сценарии.параллельно с их главной страницей.

В спецификации также обсуждается распределение рабочих по нескольким ядрам для истинного параллелизма (это незаметно обрабатывается механизмом JavaScript браузера):

В условиях преобладания многоядерных процессоров одним из способов повышения производительности является распределение вычислительно дорогостоящих задач между несколькими работниками.В [одном] примере вычислительно дорогая задача, которая должна быть выполнена для каждого числа от 1 до 10 000 000, распределена между десятью подчиненными.

yield() и setInterval() только планируют события, которые должны произойтипозже они не работают одновременно ни с чем другим.

4 голосов
/ 27 мая 2013

Мне интересно - как еще можно добиться многопоточности в JavaScript?Любые другие важные методы?

Вы можете преобразовать свой код в код JavaScript, который не имеет явных циклов или прямых вызовов функций, вместо этого код делится на небольшие единицы извыполнение, которое управляется механизмом потоков.В моем примере кода я показываю, как должна быть преобразована функция с циклами, но я упустил механизм для вызова функций просто для простоты примера.

Процесс преобразования в основном работает путем расщепления код в точках деления.Эти точки деления являются вызовами функций и циклами (как показано выше).В этом примере я использовал объекты и ключи, но на JavaScript-движках браузера может быть намного проще, если unit хранит stack как переменную объекта (т.е. хранится с использованием this.foo = barвместо stack["foo"] = bar).

Например, следующий код:

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

... примерно так:

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};
  }
}
3 голосов
/ 28 февраля 2014

Multithread.js - это библиотека для действительно простого многопоточности в JS, которая охватывает Web Workers и выполняет большую часть вашей работы за вас.:)

2 голосов
/ 06 октября 2011

Нет прямой поддержки многопоточности в JavaScript.Однако вы можете достичь этого, применяя некоторые идеи и методы.

Существуют такие методы, как:

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

здесь код JavaScript вызывается по истечении указанного времени, и мы можем использовать

window.clearTimeout(id);

для очистки.Этим мы можем достичь ложного параллелизма.

1 голос
/ 07 октября 2011

q: как еще можно достичь параллелизма в Javascript

Вы можете использовать асинхронные или неблокирующие методы.Это имеет одну из главных шуток о системе node.js.Это не совсем многопоточный, но, как правило, быстрее.

...