2013-12-23 24 views
2

我知道將對象傳輸到Web Worker會導致主線程失去所有權。我想知道是否有辦法重新獲得所有權。這Plunker(代碼如下)演示我遇到的問題。是否有可能將傳輸的ArrayBuffer返回原始類型的數組?

main.js

var worker = new Worker("worker.js"); 
var z = new Int16Array(10); 
worker.onmessage = function(e) { 
    console.log(e.data); // [0, 1, ... 10] 
    console.log(z); // [], ownership not regained here 
} 
console.log(z); // [0, 0, ... 0], original value here 
worker.postMessage(z, [z.buffer]); 
console.log(z); // [], ownership lost here 

worker.js

self.onmessage = function(e) { 
    var data = e.data; // transferred "z" from main.js 
    for (var i = 0; i < 10; i++) { 
     data[i] = i; 
    } 
    // I thought this would return ownership back to the main thread 
    self.postMessage(data, [data.buffer]); 
} 

本質上說,最終目標是從輔助線程內的主線程改變z值,而不必在收到消息後在主線程中複製結果。但是,工人似乎保留z的所有權。我誤解了什麼嗎?有沒有辦法做到這一點?

任何建議,非常感謝。

+0

我不確定,你可以在主js的onmessage'處理函數中執行'z = e.data'嗎? – Passerby

+0

實際上我正在使用WebGL緩衝區。不幸的是,設置這個變量對WebGL來說還不夠。我必須去重新綁定緩衝區。我可以讓它工作,但它並不理想。 –

+0

我想這更像是一個概念性問題。我可以想象,轉讓所有權可以爲單個實體提供兩種工作方式,但我無法弄清楚一旦所有權歸還給工人後如何歸還所有權。 –

回答

2

不,它不能這樣工作。 Int16Array只是一個包含ArrayBuffer的接口,它是存儲真實二進制數據的地方。當您轉移所有權時,Int16Array無效(設置爲0長度)。在你的工人中,新的Int16Array被創建並被分配到舊的ArrayBuffer。我裝箱這個圖像您:

image description

  1. 留言信息將刪除類型數組緩衝區。
  2. 一切不是轉換(即ArrayBuffer)是序列化到Structured clone,陣列緩衝器被轉移
  3. Int16Array對象不再緩衝,因此是無效
  4. 結構化克隆解串行化以及創建新Int16Array實例,這種情況下接收傳輸ArrayBuffer

顯然,解釋不能擁有你返回ArrayBuffer回的想法,所以類型數組仍然無效,直到永遠。

+0

感謝您的詳細解答!所以問題在於,當所有權從worker轉移回主線程時,'ArrayBuffer'不能與來自3的'Int16Array'重新關聯? –

+0

是的,據我所知,一旦傳輸緩衝區,原始的類型化數組對象就沒用了。你必須創造一個新的。除非您傳輸兆字節的od數據,否則如果需要維護原始實例中的數據,請使用副本。 –

相關問題