2013-08-12 2 views
7

В настоящее время я пишу программу, где мне приходится иметь дело с огромными массивами. Однако я могу разделить эти массивы. Теперь мой план состоит в том, чтобы обрабатывать массивы у разных веб-работников. Я никогда не работал с ними и у меня было несколько вопросов.HTML5/JS - Начать несколько веб-мастеров

1. Как я могу управлять несколькими веб-мастерами? Я попробовал для цикла ищет подобное:

for(i = 0; i < eD.threads; i++){ 
    //start workers here 
    var worker = new Worker("js/worker/imageValues.js"); 
    worker.postMessage(brightness, cD.pixels[i]); 
} 

Здесь я получаю ошибку, что объект не может быть клонирован. Что кажется логичным. Думаю, было бы лучше сохранить их в массиве?

2. Как я могу контролировать, что все закончили свою работу? (Мне нужно снова собрать массив и работать с ним позже)

3. Сколько веб-работников действительно приносит улучшения?

4. Есть ли какой-либо расширенный учебник, помимо MDN-записи?

Спасибо!

+0

Для # 2: Вы должны были бы использовать 'postMessage' от работника, чтобы отправить обратно сообщение этому родительскому JS, говорящему, что рабочий обработан (и, вероятно, передает результаты) ...поэтому вам нужно добавить слушателя 'onmessage' для каждого Рабочего в цикле. Вы сохранили бы все эти ответы, вероятно, в массиве. Когда количество ответов в массиве совпадает с количеством созданных рабочих, это должно означать, что все сделано ... и вы можете справиться с этим массивом, который вы создали. Это можно сделать «чище», используя концепцию отложенных объектов jQuery. – Ian

+1

«Нельзя клонировать» означает, что то, что вы * передаете * работнику, не может быть клонировано. Чтобы избежать условий гонки, объекты никогда не разделяются между работниками и основной нитью. Объекты должны быть либо скопированы в пространство памяти рабочего, либо (с помощью 'Blob's и типизированных массивов) основной поток может отказаться от пространства памяти для рабочего и потерять ссылку на объект. – apsillers

+0

Хорошо. Читайте об этом, но забыл. Так или иначе. Если я создаю временную переменную в цикле, сохраните массив как строку и передайте эту строку, было бы лучшим решением? Где-то я читал, что я только посылаю Strings рабочим, где-то в другом месте, что я могу передавать переменные? Спасибо вам за ваше объяснение, хотя, помогает мне начать работу! –

ответ

14

1. Как я могу запустить нескольких веб-работников? Я попробовал такую ​​петлю:

Нет проблем с созданием более одного рабочего, даже если вы не отслеживаете их в массиве. Смотри ниже.

2. Как я могу контролировать, что все закончили свою работу? (Мне нужно повторно собрать массив и поработать с ним позже)

Они могут отправить сообщение вам, когда они будут сделаны, с результатами. Пример ниже.

3. Сколько веб-работников действительно приносит улучшения?

Как долго является частью строки? :-) Ответ будет полностью зависеть от целевой машины, на которой он работает. Многие люди в эти дни имеют четыре или более ядра на своих машинах. Конечно, машина выполняет множество других вещей. Вы должны настроиться на целевую среду.

4. Есть ли какой-либо расширенный учебник, кроме MDN-записи?

Существует не так много «продвинутых» о веб-работников. :-) Я нашел this article было достаточно.

Вот пример работает пять рабочих и наблюдая за ними, чтобы сделать:

Главное окно:

(function() { 
    var n, worker, running; 

    display("Starting workers..."); 
    running = 0; 
    for (n = 0; n < 5; ++n) { 
     workers = new Worker("worker.js"); 
     workers.onmessage = workerDone; 
     workers.postMessage({id: n, count: 10000}); 
     ++running; 
    } 
    function workerDone(e) { 
     --running; 
     display("Worker " + e.data.id + " is done, result: " + e.data.sum); 
     if (running === 0) { // <== There is no race condition here, see below 
      display("All workers complete"); 
     } 
    } 
    function display(msg) { 
     var p = document.createElement('p'); 
     p.innerHTML = String(msg); 
     document.body.appendChild(p); 
    } 
})(); 

worker.js:

this.onmessage = function(e) { 
    var sum, n; 
    sum = 0; 
    for (n = 0; n < e.data.count; ++n) { 
     sum += n; 
    } 
    this.postMessage({id: e.data.id, sum: sum}); 
}; 

О состоянии гонки, что не существует : Если вы думаете с точки зрения истинного упреждающего потока, то вы можете подумать: я мог бы создать рабочего, приращение running - 1, а затем, прежде чем я создаю следующего работника, я могу получить сообщение от первого, что это сделано, декремент running - 0, и по ошибке подумайте, что все рабочие были сделаны.

Это не может произойти в среде, в которой работают веб-сотрудники. Несмотря на то, что среда приветствует запуск работника, как только он захочет, и работник вполне может закончить до того, как код, начинающийся с рабочих, будет выполнен is queue вызов функции workerDone для основной темы JavaScript. Упреждения не существует. И поэтому мы знаем, что все работники были запущены до первого вызова workerDone. Таким образом, когда running - 0, мы знаем, что все они закончены.

Заключительное примечание. В приведенном выше примере я использую onmessage = ... для подключения обработчиков событий. Естественно, это означает, что у меня может быть только один обработчик событий для объекта, с которым я это делаю. Если вам нужно иметь несколько обработчиков для события message, используйте addEventListener. Все браузеры, которые поддерживают веб-работников, поддерживают addEventListener на них (вам не нужно беспокоиться об IE attachEvent вещь).

+0

Привет, спасибо за ваш ответ. Я буду работать через это. Кусочки String на самом деле представляют собой imagaData холста, превращенного в строку. Для разрешения 1300 * 1700px вы получите массив длиной 8840000. Поэтому я решил, что я разбил массив на х частей (в зависимости от пользовательского количества потоков). Каждая часть всего массива будет обработана. Впоследствии массив imageData восстанавливается и нарисован на холст. По крайней мере, согласно моему плану: D –

+3

@stiller_leser: Похоже на то, для чего предназначались веб-работники. :-) Но я фактически не говорил о струнах в компьютерном смысле. «Как долго длится нитка?» это британская идиома, в основном означающая «На это слишком много переменных». –

+0

: D - Я не ожидал здесь идиомы. Не было слишком много идиом в школе, так долго: вы живете и учитесь. –

0

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

Функция может быть определена непосредственно в основном потоке или вызвана из внешнего файла javascript.

Функция может быть:

  • Регулярные функции методы
  • объекта
  • функции с зависимостями
  • функции с контекстом
  • анонимные функции

Базовое использование:

/* function to execute in a thread */ 
function foo(str) { 
    return str.toUpper(); 
} 

function bar(str) { 
    return str.toUpper(); 
} 

// to execute these 2 functions in 2 threads: // 

/* create objects, which you pass to vkThread as an argument*/ 
var param1 = { 
     fn: foo, 
     args: ['hello'] 
    }; 
var param2 = { 
     fn: bar, 
     args: ['world'] 
    } 

/* run thread */ 
vkThread.execAll([param1,param2]).then(
    function (data) { 
    $scope.repos = data[0] + ' ' + data[1]; // <-- HELLO WORLD 
    } 
); 

Примеров и API документ: http://www.eslinstructor.net/ng-vkthread/demo/

Надеется, что это помогает,

--Vadim

Смежные вопросы