Which operations in node are thread safe?

Go To StackoverFlow.com

11

I'm using this approach to store data in a global array hosting an http server where certain requests will manipulate the global array.

I'm kind of worried about running into threading issues with certain operations -- mainly push and splice. I imagine if one request has me iterating over the array and removing items based on a conditional, while another request has me calling .push() on the array that I'll run into issues. Can anyone confirm this?

I mostly write in C# where even a simple increment isn't thread safe (launching 25 threads that do i++, won't guarantee that i == 25 after all is said and done).

Update:

I've written 5 examples to demonstrate what I'm talking about. Test 1 and Test 3 work fine. Test 2 fails, because of well... what normally would be called threading issues (whether they are actual CPU threads or not). Test 4 and 5, when run in parallel seem to work (meaning they don't have collision problems like Test 2).

http://pastebin.com/HcJHTDFY

I'm using ApacheBench to test, making 1000 parallel requests.

This leads me to believe that Test 1 and Test 3 work fine because nodejs won't execute more than 1 instance of the app.get('/test3'...) callback in parallel javascript function in parallel (blocking?). As soon as you implement a setInterval/setTimeout, it frees up nodejs to execute another instance of the callback (non-blocking?).

I'm really just trying to understand what the heck non-blocking I/O model really means. Does it mean that "hey it's possible to do non-blocking with setTimeout and setInterval if you need non-blocking, otherwise we're going to block any other outer-level functions from being run until we exhaust the function we're on"? I feel it's imperative to know this so that I don't get myself into trouble thinking I could implement something like /test2 and be totally safe.

Also if I'm trying to be non-blocking with my callbacks, should I really be calling setTimeout(code, 1)? Or is there a better way?

2012-04-04 23:36
by Langdon


16

All are thread safe.

There are no threads, JavaScript is single threaded, it's impossible for two javascript statements to run at the same time.

As an aside, you shouldn't be using globals anyway because globals are evil

Edit:

Test 2 fails because you're using asynchronous callbacks, which means control goes back to node and it can handle more requests. This creates race conditions as seen.

In node, anything that's not asynchronous blocks. The only asynchronous things you have are setTimeout/setInterval/process.nextTick and any asynchronous IO operations.

One shouldn't manually make computation asychronous. One should just avoid doing too much computation.

I've written an article about What it means to be non-blocking

2012-04-04 23:39
by Raynos
So when nodeJs/V8 gets into a function() { } I wrote, no other functions of mine will be executed, except for the ones I call inside (as callbacks) - Langdon 2012-04-04 23:43
By the way, JavaScript might be single threaded, but nodeJS appears to be multi-threaded, otherwise subsequent requests to the built-in http server wouldn't be able to return until the first one is finished. Also http://stackoverflow.com/questions/7018093/nodejs-really-single-threade - Langdon 2012-04-04 23:45
@Langdon whether it's multi threaded or not is an implementation detail you shouldn't care about. All it does is asynchronous IO, either directly at the kernel level or emulated asynchronous IO using thread pool - Raynos 2012-04-04 23:57
But I have to care if I'm using a global variable to maintain data. Although, perhaps from what you're saying, I should reconsider my approach. I'll try to write some tests to prove/disprove what I'm thinking - Langdon 2012-04-05 00:00
@Langdon you don't care, you never see the threads. This is like asking "is SQL thread safe?". Even though the SQL engine implementation uses threads somewhere a few layers down, you never see them nor do you care about them, they are just implementation details - Raynos 2012-04-05 00:01
Would you mind checking out my update? I'm pretty sure I understand it now, but would like clarification from an expert - Langdon 2012-04-05 12:38
Much thanks for the clarification - Langdon 2012-04-05 13:07
This answer is wrong. The 'javascript is single thread' myth is long gone. Learn your skills well - almosnow 2016-02-23 19:36


-5

Raynos is mostly correct. But just because JavaScript is single threaded doesn't mean you can let your guards down. You still need to be aware of threads. A good example to illustrate this is how socket.io is maintaining connection with varies clients and still be able to keep track of these clients.

JavaScript's functional programming part works by variable binding (like...A LOT). Not being aware of threads makes you falsely assumes that your variables are the correctly bound. Like the socket.io example, how can you be sure the connection you're getting is the client you think you're getting? What if the reference binding went wrong and the connection actually references a different client?

This is the type of things you need to be careful of.

2012-04-05 00:29
by ming_codes
JavaScript does not have pass by reference. That and the nonsense your talking about has nothing to do with threads. node.js doesn't even use threads if the OS supports async IO at the kernel leve - Raynos 2012-04-05 00:29
@lightblade Haters.. - Langdon 2012-04-05 12:11
To give actual feedback/critism. When would the "reference binding go wrong". When would the connection reference a different "client". Yes there are concurrency traps you should be aware of, but your not describing them and they are not related to thread - Raynos 2012-04-05 12:59
@ming_codes You are right, your answer is right - almosnow 2016-02-23 19:36
Ads