I understand that transferring objects to a Web Worker causes the main thread to lose ownership. I am wondering if there is any way for it to regain ownership. This Plunker (code below) demonstrates the issue I am having.

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

Essentially, the end goal is to change the value of z in the main thread from within the worker thread, without having to copy the results in the main thread after the message is received. However, it seems that the ownership of z is retained by the worker. Am I misunderstanding something? Is there a way to accomplish this?

Any suggestions are greatly appreciated.

有帮助吗?

解决方案

No, it doesn't work like that. The Int16Array is just an interface wrapping over ArrayBuffer, which is where the real binary data are stored. When you transfer the ownership, the Int16Array is invalidated (set to 0 length). In your worker, new Int16Array is created and assigned to the old ArrayBuffer. I crated this image for you:

image description

  1. Post message removes buffer from the typed array.
  2. Everything that is not Transferable (that is ArrayBuffer) is serialized to Structured clone, array buffer is transfered
  3. The Int16Array object has no longer a buffer and therefore is invalid
  4. Structured clone is deserialized and that creates new Int16Array instance, this instance receives transferred ArrayBuffer

Obviously, interpreter cannot have an idea that you returned the ArrayBuffer back, so the typed array remains invalid forever.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top