74

I was going through the details of node.jsand came to know that, It supports asynchronous programming though essentially it provides a single threaded model.

How is asynchronous programming handled in such cases? Is it like runtime itself creates and manages threads, but the programmer cannot create threads explicitly? It would be great if someone could point me to some resources to learn about this.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Rakesh K
  • 8,237
  • 18
  • 51
  • 64

3 Answers3

95

Say it with me now: async programming does not necessarily mean multi-threaded.

Javascript is a single-threaded runtime - you simply aren't able to create new threads in JS because the language/runtime doesn't support it.

Frank says it correctly (although obtusely) In English: there's a main event loop that handles when things come into your app. So, "handle this HTTP request" will get added to the event queue, then handled by the event loop when appropriate.

When you call an async operation (a mysql db query, for example), node.js sends "hey, execute this query" to mysql. Since this query will take some time (milliseconds), node.js performs the query using the MySQL async library - getting back to the event loop and doing something else there while waiting for mysql to get back to us. Like handling that HTTP request.

Edit: By contrast, node.js could simply wait around (doing nothing) for mysql to get back to it. This is called a synchronous call. Imagine a restaurant, where your waiter submits your order to the cook, then sits down and twiddles his/her thumbs while the chef cooks. In a restaurant, like in a node.js program, such behavior is foolish - you have other customers who are hungry and need to be served. Thus you want to be as asynchronous as possible to make sure one waiter (or node.js process) is serving as many people as they can.

Edit done

Node.js communicates with mysql using C libraries, so technically those C libraries could spawn off threads, but inside Javascript you can't do anything with threads.

kdbanman
  • 10,161
  • 10
  • 46
  • 78
RyanWilcox
  • 13,890
  • 1
  • 36
  • 60
  • 9
    More accurately. "Node.js communicates with mysql through an asynchronous API. The implementation of the asynchronous API is in C and that implementation may just be run the synchronous API through a threadpool". The fact that the asynchronous API may use a thread pool internally is a low level detail you don't care about. – Raynos Jan 24 '12 at 19:38
  • Ah, so the mysql is running in a different thread, then it adds an event back to JS when it's done. If I wanted to make an async module of my own I could use the child processes in node to achieve the same effect. – MetaGuru Jan 29 '13 at 17:01
  • 3
    i think it's really better to avoid the very word 'thread' here—people jump to false conclusions when they hear it. an asynchronous call may use a thread, or fork a process, or do whatever; important thing is, there may occur a callback or an event later in the event loop. – flow May 09 '13 at 18:00
13

Ryan said it best: sync/async is orthogonal to single/multi-threaded. For single and multi-threaded cases there is a main event loop that calls registered callbacks using the Reactor Pattern. For the single-threaded case the callbacks are invoked sequentially on main thread. For the multi-threaded case they are invoked on separate threads (typically using a thread pool). It is really a question of how much contention there will be: if all requests require synchronized access to a single data structure (say a list of subscribers) then the benefits of having multiple threaded may be diminished. It's problem dependent.

As far as implementation, if a framework is single threaded then it is likely using poll/select system call i.e. the OS is triggering the asynchronous event.

Frank
  • 3,029
  • 5
  • 34
  • 43
4

To restate the waiter/chef analogy:

Your program is a waiter ("you") and the JavaScript runtime is a kitchen full of chefs doing the things you ask.

The interface between the waiter and the kitchen is mediated by queues so requests are not lost in instances of overcapacity.

So your program is assigned one thread of execution. You can only wait one table at a time. Each time you want to offload some work (like making the food/making a network request), you run to the kitchen and pin the order to a board (queue) for the chefs (runtime) to pick-up when they have spare capacity. The chefs will let you know when the order is ready (they will call you back). In the meantime, you go wait another table (you are not blocked by the kitchen).

So the accepted answer is misleading. The JavaScript runtime is definitionally multithreaded because I/O does not block your JavaScript program. As a waiter you can continue serving customers, while the kitchen cooks. That involves at least two threads of execution. The reality is that the runtime will maintain several threads of execution behind the scenes, in order to efficiently serve the single thread directly corresponding to your script.

By design, only one thread of execution is assigned to the synchronous running of your JavaScript program. This is a good thing because it makes your program easier to reason about than having to handle multiple threads of execution yourself. Don't worry: your JavaScript program can still get plenty complicated though!

Ben Aston
  • 53,718
  • 65
  • 205
  • 331