многоядерное программирование с использованием JavaScript? - PullRequest
17 голосов
/ 15 декабря 2010

Итак, у меня есть эта серьезно рекурсивная функция, которую я хотел бы использовать с моим кодом. Проблема в том, что он не использует преимущества двухъядерных машин, потому что js однопоточный. Я пытался использовать веб-работников, но на самом деле мало знаю о многоядерном программировании. Кто-нибудь укажет мне на материал, который может объяснить, как это делается. Я гуглил, чтобы найти эту примерную ссылку , но это не очень помогает без документации! = /

Я был бы рад, если бы кто-нибудь показал мне, как это можно сделать без веб-работников! Это было бы просто потрясающе! =)

Я натолкнулся на эту ссылку на whatwg . Это действительно странно, потому что объясняет, как использовать многоядерное программирование в веб-приложениях и т. Д., Но при запуске в моем браузере Chrome выдает ошибки. То же самое относится и к другим браузерам.

Ошибка: 9Uncaught ReferenceError: Рабочий не определен в worker.js

Ответы [ 3 ]

11 голосов
/ 30 мая 2012

ОБНОВЛЕНИЕ (2018-06-21) : Для людей, которые приходят сюда в поисках многоядерного программирования на JavaScript, не обязательно браузер JavaScript (для этого ответ * 1005) * все еще применяется как есть ): Node.js теперь поддерживает многопоточность за флагом функции (--experimental-workers): информация о выпуске , соответствующая проблема .


Списание этого с головы до головы, никаких гарантий для исходного кода. Пожалуйста, успокойся на мне.

Насколько я знаю, вы не можете программировать потоки с помощью JavaScript. Веб-работники являются формой мульти-программирования; все же JavaScript по своей природе однопоточный (основан на цикле событий).

Веб-работник - это отдельный поток выполнения в том смысле, что он ничего не делит со скриптом, который его запустил; нет ссылки на глобальный объект скрипта (обычно называемый «окном» в браузере), и нет ссылки ни на какие переменные вашего основного скрипта, кроме данных, которые вы отправляете в поток.

Думайте, как веб-работник, как о маленьком "сервере", которому задают вопрос и дают ответ. Вы можете отправлять только строки на этот сервер, и он может только анализировать строку и отправлять обратно то, что он вычислил.

// in the main script, one starts a worker by passing the file name of the 
// script containing the worker to the constructor. 
var w = new Worker("myworker.js");

// you want to react to the "message" event, if your worker wants to inform
// you of a result. The function typically gets the event as an argument. 
w.addEventListener("message",
    function (evt) {
        // process evt.data, which is the message from the 
        // worker thread
        alert("The answer from the worker is " + evt.data);
    });

Затем вы можете отправить сообщение (строку) в эту тему, используя ее postMessage () - Метод:

w.postMessage("Hello, this is my message!");

Пример рабочего сценария (сервер «эхо») может быть:

// this is another script file, like "myworker.js"
self.addEventListener("message", 
    function (evt) {
        var data = JSON.parse(evt.data);
        /* as an echo server, we send this right back */
        self.postMessage(JSON.stringify(data))
    })

все, что вы публикуете в этой теме, будет декодировано, перекодировано и отправлено обратно. конечно, вы можете делать любую обработку, которую захотите сделать между ними. Этот работник останется активным; вы можете вызвать terminate() на нем (в вашем основном скрипте; это будет w.terminate()), чтобы завершить его, или вызвать self.close() на вашем работнике.

Подводя итог : что вы можете сделать, это сжать параметры вашей функции в строку JSON, которая отправляется с использованием postMessage, декодируется и обрабатывается «на другой стороне» (на рабочем месте) , Результат вычислений отправляется обратно в ваш «основной» скрипт.

Объяснить, почему это не так просто : Расширение взаимодействия на самом деле невозможно, и это ограничение является преднамеренным. Поскольку общие ресурсы (объект, видимый как рабочему, так и основному сценарию) будут подвергаться воздействию двух потоков, мешающих им одновременно, вам необходимо будет управлять доступом (то есть блокировкой) к этому ресурсу, чтобы предотвратить состояние гонки. ,

Подход, основанный на передаче сообщений и не имеющий общего доступа, не так хорошо известен, главным образом потому, что большинство других языков программирования (например, C и Java) используют потоки, которые работают в одном и том же адресном пространстве (в то время как другие, например, Erlang, например, нет). Учтите это:

  • действительно трудно кодировать большой проект с мьютексами (механизм взаимного исключения) из-за связанных сложностей взаимоблокировки / состояния гонки. Это то, что может заставить взрослых плакать!
  • Это действительно легко по сравнению с передачей сообщений, без разделения семантики. Код изолирован; вы точно знаете, что входит в ваш работник и что выходит из вашего работника. Тупики и условия гонки невозможно достичь!

Просто попробуйте; он способен делать интересные вещи, наверное, все, что вы хотите. Имейте в виду, что реализация все еще определена, насколько я знаю, использует ли она преимущества многоядерности.

NB. Я только что узнал, что по крайней мере некоторые реализации будут обрабатывать JSON-кодирование сообщений для вас.

Итак, чтобы дать ответ на ваш вопрос (все выше; версия tl; dr): Нет, вы не можете сделать это без веб-работников. Но в веб-работниках нет ничего плохого, кроме поддержки браузера, как в случае с HTML5 в целом.

4 голосов
/ 15 декабря 2010

Насколько я помню, это возможно только с новым стандартом HTML5.Ключевое слово "Web-Worker"

См. Также:

HTML5: JavaScript Web Workers

Потоки JavaScript с HTML5 Web Workers

2 голосов
/ 09 октября 2018

Веб-работники являются ответом на стороне клиента.Для NodeJS есть много подходов.Самый популярный - порождение нескольких процессов с помощью pm2 или аналогичного инструмента.Запустите отдельный процесс и дочерние процессы spawn / fork.Вы можете обойти их и найти множество примеров и тактик.

Веб-работники уже хорошо поддерживаются всеми браузерами.https://caniuse.com/#feat=webworkers

API и образцы: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers

enter image description here

...