Подтвердить что ты не робот

Многопоточность JavaScript

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

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

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

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

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

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

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

Процесс преобразования в основном работает, разбивая код в точках деления. Эти точки деления - это вызовы функций и циклы (как показано выше). В примере я использовал объекты и ключи, но может быть намного проще в JavaScript-браузере браузера, если единицы хранят стек как объектную переменную (т.е. Сохраняют с помощью 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

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

Ответ 4

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

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

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

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

window.clearTimeout(id);

для очистки. Благодаря этому мы можем достичь поддельных concurrency.

Ответ 5

q: как еще вы можете достичь concurrency в Javascript

Вы можете использовать методы типа async или 'non-blocking'. Это один из главных жуков в системе node.js. Это не совсем многопоточное, но оно имеет тенденцию быть быстрее.