I have always thought that web workers create separate threads, but today I ran into the spec on w3c website. Below is a citation about web workers:
This allows for thread-like operation with message-passing as the
coordination mechanism.
The question is - if it is thread-like, not actual thread what is an advantage(performance wise) of using this technology?
Any help will be appreciated!
Yes, web workers create actual threads (or processes, the spec is flexible on this). According to the Web Workers specification, when a worker is created the first step is:
Create a separate parallel execution environment (i.e. a separate thread or process or equivalent construct), and run the rest of these steps in that context.
For the purposes of timing APIs, this is the official moment of creation of the worker.
(W3C Web Workers specification section 4.4)
So it is explicitly specified that code running in Web Workers run in actual threads or processes.
Although it is possible to implement Workers without threads (note the "equivalent construct" language) for use on systems that don't support threads, all browser implementations implement Web Workers as threads.
A web worker runs in a single thread isolated from the main thread, the way they pass messages around is thread-like and works differently depending on whether you're using dedicated (can only be accessed from the script that created it) or shared (can be accessed by any script within the same domain via a port object) workers.
EDIT:
Updated answer to reflect my comment from months ago. While a SINGLE web worker runs in an isolated thread it doesn't mean each additional worker will run in the same thread.
According to MDN,
Web Workers are a mechanism by which a script operation can be made to run in a background thread separate from the main execution thread of a web application. The advantage of this is that laborious processing can be performed in a separate thread, allowing the main (usually the UI) thread to run without being blocked/slowed down.
So, each worker does not create a separate thread, but all workers are running in a single separate thread.
I guess, like just in other things, the implementation and approach may differ from browser to browser.
Related
I always believed that JS was a single threaded language which makes it inefficient for CPU intensive tasks. I recently came across worker threads and how it solves this inefficiency problem by creating "multiple worker threads under one process". What's the difference between a process and a thread? Why is JS all of the sudden capable of spawning multiple worker threads that help and interact with the main JS thread to enable concurrency? Could you help me understand this topic in layman terms? Thank you
Starting in node v10, they introduced WorkerThreads. A WorkerThread is an entirely new instance of the V8 Javascript interpreter. It has it's own set of variables, it's own globals and it's own thread of running Javascript. You cannot directly share regular Javascript variables between the main thread and a workerThread or between workerThreads.
You can directly share memory if it is specifically allocated as SharedMemory such as a SharedArrayBuffer, but when doing so, you open yourself up to race conditions between the two threads both accessing the Shared memory. So, you have to either use Atomics or your own concurrency management scheme to prevent race conditions when modifying the shared memory.
The main thread and workerThreads can send messages to each other and those messages can contain some types of data structures that will be copied via a structured cloning mechanism and sent to the other V8 instance.
The idea behind workerThreads is that they are useful for getting CPU-intensive code out of your main event loop (particularly useful for servers) so you can fire up one or more workerThreads to handle CPU-intensive work and keep the main thead event loop free and responsive to incoming events/networking/etc...
You can also do something similar by creating multiple nodejs processes. But, a process is a heavier-weight thing than a workerThread and workerThreads allow you to share memory with SharedMemory whereas separate processes do not.
From the Mozilla documentation:
Web Workers is a simple means for web content to run scripts in
background threads.
Considering Javascript is single-threaded, are web workers separate threads or processes? Is there shared memory that classifies them as threads?
They run in background threads, but the API completely abstracts from the implementation, so you may come across a browser that just schedules them to run on the same thread as other events like Node does. Processes are too heavyweight to run background tasks.
Considering Javascript is single-threaded
JavaScript is not single-threaded.
The main part of a JavaScript program runs on an event loop.
Long-running processes (XMLHttpRequest being the classic example) are almost always farmed out to stuff that runs outside the event loop (often on different threads).
Web Workers are just a means to write JavaScript that runs outside the main event loop.
are web workers separate threads or processes? Is there shared memory that classifies them as threads?
That's an implementation detail of the particular JS engine.
As per the MDN:-
The Worker interface spawns real OS-level threads, and mindful programmers may be concerned that concurrency can cause “interesting” effects in your code if you aren't careful.
Reference:- https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers#about_thread_safety
The documentation does not define whether the web worker runs in a separate thread or process (or another similar construct). So, depending on the hardware architecture of the processor on which the program is executed, the Operating System and the implementation of the JavaScript engine used, it may be different.
However, I guess that the essence of this question is: Can the Operating System use multiple CPU cores by using web workers? If so, the answer is: YES!!! Even regardless of the implementation of the JavaScript engine!
As long as the processor has many cores, and the Operating System can make use of them, even if the Web Worker's script is executed within another thread of the same process, these threads will be able to run on different cores because the "process" is a construct of an Operating System and itself can run on several processor cores, just as several processes can run on a single core.
P.S. If you want the code to be executed 100% in another process, delegate it to another service (e.g. running on a different server).
I don't understand how web-workers works... Are web-workers parallel or just preempted?
Is it safe for a web-workers to render to a webgl context?
If I have only a web-worker rendering to webgl context, and my main "thread" is not invoking the worker also, is it safe to the web-worker to render to the webgl context?
When a Web Worker is created, you give it a URI pointing to a JavaScript file. It loads that JavaScript file in a new OS-level thread. You can't control affinity to specific cores or thread priorities, (as of this writing), but the underlying Thread created is real and unfettered. By default, JavaScript running in a Web Worker's thread has NO access to the DOM: you are not given access to the window object nor any DOM-related Classes.
The semantics of the Web Worker thread make it nearly completely unmoored from the default DOM thread. First thing that's interesting is that the Web Worker can run in 100% CPU usage infinite loops without worrying about freezing up the UI. This means the dreaded "Warning: Unresponsive script" message box cannot be triggered by a Web Worker!
The tradeoff of being unmoored is your ability to synchronize and communicate between DOM and worker threads is limited. The explicit conduit between worker and DOM is the postMessage() API for sending data and the onmessage event for receiving events. You can postMessage with strings and objects where your data is cloned from source thread's heap into target thread's heap. onmessage events are only received by your Web Worker when it is idle. This means, in order for onmessage events to be delivered from the DOM to your Web Worker in a timely fashion, the worker must yield frequently; this may put a wrinkle in the way you want to write your code.
It's important to understand that there are a special class of "Transferable Objects" in modern JavaScript implementations where objects that you send to postMessage() are not cloned, but rather ownership of the object is transferred from one thread to another. These are the types of data you want to send to postMessage() whenever possible; any time data is cloned when calling postMessage(), you create TONS of garbage to be GC'd and system performance will suffer.
The collection of Transferable Object types out there has been steadily growing, and the Mozilla Development Network, WhatWG, and W3C are great places to watch the spec research in this area. I couldn't even tell you all of the things that can be Transferred across threads in the browser nowadays, but if I made you a comprehensive list, it'd likely be out of date in a year or less.
Regarding your original question, on Firefox 44+, you can now partially transfer a Canvas to a WebWorker via the HTMLCanvasElement#transferControlToOffscreen function. transferControlToOffscreen creates a Transferable OffscreenCanvas object that you can postMessage over to a Web Worker. On the Web Worker, you can acquire a webgl CanvasContext and issue drawing commands to the canvas from the worker thread without having direct access to the actual canvas tag's DOM that still lives over with the DOM thread.
https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/transferControlToOffscreen
https://hacks.mozilla.org/2016/01/webgl-off-the-main-thread/
This question has an answer that basically states you can't use webgl from a web worker as web workers don't have access to the DOM and you have to call getContext() on a canvas object to get the webgl context.
Are there any synchronization primitives like Barriers, Semaphors, Locks, Monitors, ... available in JavaScript / Web Workers or is there some library available empowering me to make use of such things (I'm thinking of something like java.util.concurrent in Java)?
Do Workers have obscure properties which differentiate them from Threads (can they share memory with the main thread, for example)? Is there some kind of limit how many workers can be spawned (like, for security reasons or something...)? Do I have to take special care of something?
Web workers don't have a concept of shared memory; all messages that are passed between threads are copied. With that being said, you don't have Barriers, Semaphores, Locks, and Monitors, because you don't need them in the web worker model.
The concept of shared memory was proposed back in Feb 2011 but the status is now wontfix due to developer complexity =>
https://lists.webkit.org/pipermail/webkit-unassigned/2011-February/287595.html
There is also a nice blurb about web workers here.
http://blogs.msdn.com/b/ie/archive/2011/07/01/web-workers-in-ie10-background-javascript-makes-web-apps-faster.aspx
Hope this helps
In short: no there aren't any synchronization primitives in javascript but there is also no need for them since JavaScript is inherently single threaded :). Workers can only access there own scope (no dom manipulation just calculations) and send messages to the main ui thread where the normal js resides. I'm not sure about the maximum count of workers but there sure is a limit, you could try it out in a browser :)
Hope this helps!
Here you have a library based on jQuery made for that purpose: http://www.megiddo.ch/jcon-q-rency.
Of course the model is not really identical to java.util.concurrent since we are not dealing with the same environment, as explained in the other answers...
Based on my understanding, only I/O in NodeJS is non-blocking. If we do, for example, lots of heavy math operations, other users cannot access to the server until it's done.
I was wondering if there is a non-blocking way to do heavy computation in NodeJS? Just curious.
If you have long-running calculations that you want to do with Node, then you will need to start up a separate process to handle those calculations. Generally this would be done by creating some number of separate worker processes and passing the calculations off to them. By doing this, you keep the main Node event loop unblocked.
On the implementation side of things, you have two main options.
The first being that you manually spin off child processes using Node's child-process API functions. This one is nice because your calculations wouldn't even have to be javascript. The child process running the calculations could even be C or something.
Alternatively, the Web Worker specification, has several implementations available through NPM if you search for 'worker'. I can't speak to how well these work since I haven't used any, but they are probably the way to go.
Update
I'd go with option one now. The current child process APIs support sending messages and objects between processes easily in a worker-like way, so there is little reason to use a separate worker module.
You can use Hook.io to run a separate node process for your heavy computation and communicate between the two. Hook.io is particularly useful because it has auto-healing meshes meaning that if one of your hooks (processes) crashes it can be restarted automatically.
Use multiple NodeJS instances and communicate over sockets.
Use multiple node instances and communicate over node-zeromq, HTTP, plain TCP sockets, IPC (e.g. unix domain sockets), JSON-RPC or other means. Or use the web workers API as suggested above.
The multiple instances approach has its advantages and disadvantages. Disadvantages are that there is a burden of starting those instances and implementing own exchange protocols. Advantages are that scaling to many computers (as opposed to many cores/processors within a single computer) is possible.
I think this is way to late, but this is an awesome feature of nodejs you've to know about.
The only way abot multithreading is by spawning new processes, right so far.
But nodejs has an implemented message feature between spawned node-forks.
http://nodejs.org/docs/latest/api/child_processes.html#child_process.fork
Great work from the devs, you can pass objects etc. as message to your childs and backwards
You can use node cluster module.
https://nodejs.org/api/cluster.html
I would use JXCore - it's a polished nodejs based engine which runs your code but has several options including the multi threading you are searching for. Running this in production is a charm!
Project's source: https://github.com/jxcore/jxcore
Features include:
Support for core Node.JS features
Embeddable Interface
Publish to Mobile Platforms (Android, iOS ..)
Supports Multiple JavaScript Engines
Multi-threading Capabilities
Process Configuration & Monitor
In-memory File System
Application Packaging
Support for the latest JavaScript features (ES6, ASM.JS ...)
Support for Universal Windows Platform (uwp) api