Javascript allows buffers to be transfered from a source thread to a Worker thread. Otherwise, the ArrayBuffer is copied, then passed to the worker. Transfered buffers are not accessible ("neutered") in the source thread [1]:
// create data that can be transfered var arr = new Uint8Array(5); // outputs: 5 console.log(arr.buffer.byteLength); var worker = new Worker("some_worker.js"); // transfer the buffer worker.postMessage({arr: arr}, [arr.buff]); // the buffer vanishes. is "Neutered" // outputs: 0 console.log(arr.buffer.byteLength);
I unterstand how the mechanism works. I am however curious why it was introduced. Why isn't the data shared between worker threads, like in a traditional threading model, which allows multiple threads to access the same memory region?
Other phrasings of the same question for clarification:
Why are buffer neutered on transfer? / What is the reasoning behind this mechanism? / Why was it introduced? Why can't memory regions be shared between Workers?
I am looking for an answer drawing from credible and/or official sources.
[1] https://developer.mozilla.org/en/docs/Web/API/Worker/postMessage
Transferable objects were introduced in Web Workers in order to improve performance versus copying objects (especially when we're talking about objects of big size). It can be parallelised to a comparison between pass-by-value and pass-by-reference in common programming languages (such as C/C++).
The further restriction, that transferable objects cannot be used in the source worker thread, was probably added, so that it is guaranteed that there will be no race conditions between the 2 different threads (in order to facilitate the work of developers that do not have to care about that). Furthermore, there would also then be a need for a lot more concurrency primitives to be implemented in Javascript (such as mutexes etc.). In essence, the use of "transfer" means you just intend to transfer the data to another thread, not use them from 2 threads simultaneously, so we could say that the implementation makes sense.
In general, Web Workers were not designed as a shared-memory model, but as as a message-exchange model.
For further reading on performance difference, check this. You can also check this, where there is a discussion why shared memory model has not been adopted for Web Workers in WebKit.
This is a very basic multi-threading question. If the Array was accessible in both the main thread and the worker, then a mutex lock would have to be implemented so that race conditions won't appear when accessing the buffer. Also, I think Array buffers are usually used when you want performance, but having a lock for reading/writing data from that buffer would make the worker slower.
I guess this is one of the reasons why the resource is "moved" and not shared.
TL;DR: multi-threading
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With