2013-08-12 24 views
7

Tôi hiện đang viết một chương trình, nơi tôi phải xử lý các mảng lớn. Tuy nhiên tôi có thể chia các mảng đó. Kế hoạch của tôi bây giờ là xử lý các mảng trong các công nhân web khác nhau. Tuy nhiên, tôi chưa bao giờ làm việc với họ và có một vài câu hỏi:HTML5/JS - Bắt đầu một số webworkers

1. Tôi sẽ chạy một vài công nhân web như thế nào? Tôi đã thử một vòng lặp như sau:

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

Ở đây tôi nhận được lỗi, rằng đối tượng không thể được nhân bản. Điều đó có vẻ hợp lý. Tôi đoán nó sẽ là tốt hơn để lưu chúng trong một mảng?

2. Làm cách nào để kiểm soát tất cả công việc đã hoàn thành? (Tôi cần phải nối lại mảng và làm việc với nó sau)

3. Có bao nhiêu công nhân thực sự cải thiện?

4. Có hướng dẫn nâng cao nào ngoài mục nhập MDN không?

Cảm ơn bạn!

+0

Đối # 2: Bạn sẽ phải sử dụng 'postMessage' từ Worker để gửi lại một tin nhắn cho phụ huynh này JS nói rằng công nhân được xử lý xong (và có thể vượt qua các kết quả) ...vì vậy bạn phải thêm một trình nghe 'onmessage' cho mỗi Worker, trong vòng lặp. Bạn sẽ lưu trữ tất cả các phản hồi này trong một mảng. Khi số lượng phản hồi trong mảng giống với số lượng công nhân được tạo, điều đó có nghĩa là tất cả được thực hiện ... và bạn có thể xử lý mảng đó mà bạn đã tạo. Điều này có thể được thực hiện "sạch hơn" bằng cách sử dụng khái niệm các đối tượng trì hoãn của jQuery – Ian

+1

"Không thể nhân bản" ở đây có nghĩa là những gì bạn đang * chuyển đến * công nhân không thể nhân bản. Để tránh điều kiện chạy đua, vật thể không bao giờ được chia sẻ giữa công nhân và sợi chính. Đối tượng phải được sao chép vào không gian bộ nhớ của người lao động, hoặc (với 'mảng' và mảng đã nhập), luồng chính có thể từ bỏ không gian bộ nhớ cho một nhân viên và mất tham chiếu đến đối tượng. – apsillers

+0

Ok. Đọc về nó, nhưng quên nó đi. Dù sao. Nếu tôi tạo một biến tạm thời trong vòng lặp, hãy an toàn mảng như một chuỗi và truyền chuỗi đó vào, đó có phải là giải pháp tốt hơn không? Một nơi nào đó tôi đọc, rằng tôi chỉ gửi chuỗi cho công nhân, ở một nơi khác nó nói, rằng tôi có thể chuyển các biến? Cảm ơn cả hai vì lời giải thích của bạn mặc dù, giúp tôi để bắt đầu! –

Trả lời

14

1. Làm cách nào để chạy một số công nhân web? Tôi đã thử một vòng lặp như sau:

Không có vấn đề gì với việc tạo nhiều hơn một công nhân, ngay cả khi bạn không theo dõi chúng trong một mảng. Xem bên dưới.

2. Làm cách nào để kiểm soát tất cả công việc đã hoàn thành? (Tôi cần phải chỉnh sửa lại mảng và làm việc với nó sau)

Họ có thể gửi lại tin nhắn cho bạn khi kết quả đạt được. Ví dụ bên dưới.

3. Có bao nhiêu công nhân thực sự cải thiện?

Bao lâu là một đoạn chuỗi? :-) Câu trả lời sẽ phụ thuộc hoàn toàn vào máy mục tiêu mà trên đó máy đang chạy. Rất nhiều người trong những ngày này có bốn hoặc nhiều lõi trên máy của họ. Tất nhiên, máy cũng đang làm rất nhiều thứ khác nữa. Bạn sẽ phải điều chỉnh cho môi trường mục tiêu của bạn.

4. Có hướng dẫn nâng cao nào ngoài mục nhập MDN không?

Không có nhiều "nâng cao" về nhân viên web. :-) Tôi tìm thấy this article là đủ.

Dưới đây là một ví dụ chạy năm công nhân và quan sát để họ được thực hiện:

cửa sổ chính:

(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}); 
}; 

Về điều kiện chủng tộc mà không tồn tại : Nếu bạn nghĩ về luồng thực sự ưu tiên, thì bạn có thể nghĩ: Tôi có thể tạo công nhân, tăng số running đến 1, và sau đó trước khi tôi tạo công nhân tiếp theo tôi có thể nhận được tin nhắn từ người đầu tiên mà nó được thực hiện, giảm running đến 0, và nhầm lẫn nghĩ rằng tất cả các công nhân đã được thực hiện.

Điều đó không thể xảy ra trong môi trường làm việc của người lao động. Mặc dù môi trường được chào đón để bắt đầu công nhân ngay khi họ thích, và nhân viên có thể hoàn thành trước khi mã bắt đầu là xếp hàng cuộc gọi đến chức năng workerDone cho chuỗi JavaScript chính. Không có trống trước. Và vì vậy chúng tôi biết rằng tất cả các công nhân đã được bắt đầu trước khi cuộc gọi đầu tiên đến workerDone thực sự được thực thi. Do đó, khi running0, chúng tôi biết tất cả đều đã hoàn tất.

Lưu ý cuối cùng: Ở trên, tôi đang sử dụng onmessage = ... để kết nối trình xử lý sự kiện. Đương nhiên điều đó có nghĩa là tôi chỉ có thể có một trình xử lý sự kiện trên đối tượng mà tôi đang làm. Nếu bạn cần có nhiều trình xử lý cho sự kiện message, hãy sử dụng addEventListener. Tất cả các trình duyệt hỗ trợ nhân viên web hỗ trợ addEventListener trên chúng (bạn sẽ không phải lo lắng về điều IE attachEvent).

+0

Xin chào, cảm ơn câu trả lời của bạn. Tôi sẽ làm việc thông qua nó. Các phần của String thực sự là imagaData của canvas được biến thành một chuỗi. Đối với một độ phân giải 1300 * 1700px bạn kết thúc với một mảng với chiều dài 8840000. Vì vậy, tôi figured tôi chia mảng thành x miếng (tùy thuộc vào một số người dùng có thể kiểm soát các chủ đề). Mỗi phần của toàn bộ mảng sẽ được xử lý. Sau đó mảng imageData được xây dựng lại và được vẽ lên canvas. Ít nhất theo kế hoạch của tôi: D –

+3

@stiller_leser: Âm thanh giống như loại công việc web có ý nghĩa. :-) Nhưng tôi đã không thực sự nói về dây trong ý nghĩa máy tính. "Bao lâu là một mảnh của chuỗi?" là một thành ngữ người Anh, về cơ bản có nghĩa là "Có quá nhiều biến để trả lời câu hỏi đó". –

+0

: D - Tôi không mong đợi một thành ngữ ở đây. Không có quá nhiều thành ngữ ở trường, quá lâu: Bạn sống và học hỏi. –

0

stiller_leser. Nếu bạn vẫn khắc phục sự cố, hãy xem plugin ng-vkthread. Nó cho phép bạn thực hiện kỹ thuật tính toán song song mà bạn đang cố gắng phát triển trong dự án của mình. Với plugin này, bạn có thể thực hiện nhiều chức năng trong nhiều luồng cùng một lúc.

Chức năng có thể được xác định trực tiếp trong chuỗi chính hoặc được gọi từ tệp javascript bên ngoài.

Chức năng có thể là:

  • chức năng thường xuyên
  • phương pháp đối tượng của
  • Chức năng với phụ thuộc
  • Chức năng với bối cảnh
  • Anonymous chức năng

sử dụng cơ bản:

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

Các ví dụ và API doc: http://www.eslinstructor.net/ng-vkthread/demo/

Hope this helps,

--Vadim

Các vấn đề liên quan