3 ms·
Node.js is cooperatively multitasked. VxWorks (and Erlang) are preemptively multitasked. So the basic structure is quite different. If one of your node.js event
by jlouis 14y ago
Node.js is cooperatively multitasked. VxWorks (and Erlang) are preemptively multitasked. So the basic structure is quite different. If one of your node.js events infinite loops, it is game over. Be it web server or rover. Not so here.
- dllthomas 14y agoThough, with the coding standards forbidding any recursion (direct or indirect) and requiring statically bounded loops, you're not going to have an infinite loop anyway (or, incidentally, write a UTM).
- jeremiep 14y agoNode.js is preemptive, there's only one thread running JavaScript but multiple C++ worker threads doing work on behalf of the script. vibe.d on the other hand is cooperative since it uses coroutines for concurrency.
- malkia 14y agoPlease, explain what do you mean by that - "pre-emptive"? My understanding (coming from C and OS terms) is that pre-emptive means taken over. e.g. if I have a real OS thread it is being temporarily "paused" and the resources (CPU/mem/io) are given to something else. At some point control is restored back. But this is without the knowledge or instructions from the thread itself. So things like priority inversions are hard to battle with pre-emptive multitasking - for example thread A with low priority holding a mutex, while thread B with higher priority waits for it. (and no need for mutexes, if only message passing is to be used).
- jeremiep 14y agoThe node.js worker threads are native threads, which are preemptive on all current platforms. The JavaScript context is running an event loop which most likely must perform locking on its message queue and callbacks to async operations are queued for execution on a future tick of this event loop. All of this seems very preemptive to me. What seems like cooperation in node.js is really just async operations queuing up on the event loop. Since requests are also async events, they get interlocked with callbacks from existing requests. To me, cooperation is when you yield the thread to another coroutine. This saves the state of the call stack, the registers, everything; meaning you don't force your user to keep that state in closures. The user code in a cooperative environment feels sequential and blocking and results are passed by return values, not by calling continuations. Its also friendlier to exceptions since it doesn't lose the entire call stack; with node.js you only get the stack since the beginning of the current event loop's tick.
- deno 14y ago> The JavaScript context is running an event loop which most likely must perform locking on its message queue and callbacks to async operations are queued for execution on a future tick of this event loop. All of this seems very preemptive to me. There’s a single loop which blocks until the task yields while waiting on the result from one of the worker threads. That’s cooperation. All queued connections are starved until that happens. In Erlang, or just with pthreads, the connections are processed independently. Think separate event loops for each connection. > To me, cooperation is when you yield the thread to another coroutine. This saves the state of the call stack, the registers, everything; meaning you don't force your user to keep that state in closures. The user code in a cooperative environment feels sequential and blocking and results are passed by return values, not by calling continuations. That has noting to do with how execution is scheduled. Cooperative scheduling requires passing continuations[1], so the execution can be resumed while it waits. The simplest implementation is to use callbacks, the way node.js does it. Futures and deferreds[2] are a little bit more sophisticated (Python’s Twisted, probably something for node.js exists as well), as they allow for better composition. And of course you can hide the continuations entirely, which can be done in both Scala (compiler plugin) and Python (gevent or using generators), rewriting the direct control flow by breaking it on yield points automatically (this is how exception throws work in most languages btw), but the limitations inherent in having a single event loop per thread will still exist. [1] https://en.wikipedia.org/wiki/Continuation-passing_style https://en.wikipedia.org/wiki/Continuation-passing_style [2] https://en.wikipedia.org/wiki/Futures_and_promises https://en.wikipedia.org/wiki/Futures_and_promises
- ricardobeat 14y ago> a single loop which blocks until the task yields while waiting on the result from one of the worker threads Yes, node.js is cooperative, yet since all I/O is asynchronous the time spent blocking is mostly dispatching and simple operations, it doesn't block while waiting - that's where it's performance and high concurrency comes from. Doing CPU-heavy work in the server/main process is a no-no.
- deno 14y ago