Hacker News new | ask | show | jobs
by zzzcpan 3700 days ago
> I understand exactly when and where my javascript code will be interrupted

That's why callbacks, promises, async/await and all that are neither multitasking, nor multithreading. They are all about control, while multithreading is all about parallelism and is essentially a very low-level specialized thing, that nobody should be using, unless absolutely necessary.

3 comments

> multithreading is all about parallelism

This just isn't true. Why do you think people wrote multi-threaded applications back when almost all machines had just one processor and just one core? Threads give you concurrency as well, even if you don't want or need parallelism.

Of course they do. Anything can give you concurrency. But pretty much anything can make concurrency easier, than threads.

> Why do you think people wrote multi-threaded applications back when almost all machines had just one processor and just one core?

Almost none did. Popular networking servers were either preforking, forking or asynchronous. Desktop GUIs were event driven. Threads weren't even very usable on most systems at that time, i.e. up until a decade and a half ago or so, weren't they?

Threads weren't very usable on most systems until around 2001? No, I don't know where you've got that idea from but it's not the case.

Java had threads in 1996. The Windows 32 API had threads from at least Windows 95. Windows NT had them since 1993. I don't know when Linux got threads and couldn't find anything, but I would presume it was the mid 90s at the very latest. In fact I don't think any of these threading APIs will have even changed much since the mid 90s. They weren't new ideas at the time either!

Look at this thread programming manual from 1994 which on page 3 lists five benefits of using threads at the time, only one of which is utilising the relatively rare multiprocessors. http://www4.ncsu.edu/~rhee/clas/csc495j/MultithreadedProgram...

Linux got threads in 1996 when kernel 2.0 introduced the "clone" syscall, allowing multiple processes to share address space. LinuxThreads was built on top of this to implement the pthreads api.
I was using threads on Windows NT in 1998 (on single core, single processor machines). They were perfectly reliable.
Multi-threading was far more popular on Windows then other OSs because starting new processes was so damned expensive.

On many other systems the overhead of bringing up a new process was so much closer to that of bringing up a new thread that you only needed threads for really high performance parallel code and/or when you needed fast shared memory and/or were very memory constrained. Any time the individual tasks are fairly independent, had noticeable bottlenecks other then CPU, and data larger then the process itself, say a web server, processes were more than adequate and you don't need to worry about certain potential concurrency issues.

Yes, this is all true. But also many threading implementations (especially Linux) back then were pretty bad. Solaris and Windows were the only places where it made sense to use them.

See also "Green Threads" in early Java implementations.

Exactly. Threading actually enables a simple asynchronous blocking programming model through locks (at the expense of introducing loads of potential locking hazards).
Blocking presumes synchronicity. Locks are by definition synchronization primitives.
Great point. I find myself reminding people about this all too often.
Well, I'm old enough to remember coding for Mac OS 8, where "multitasking" was indeed cooperative - I had to say "oh, you can interrupt me here, if you want" at different places in my code, which meant bad actors could lock the system of course. It wasn't great.

On the other hand, in the uncommon event I do have some weird javascript thing that's going to take a long time (say, parsing some ridiculously-big JSON blob to build a dashboard or something), I know I can break up my parse into promises for each phase and that I won't be locking up other UI processing as badly during that process. So: not exactly multitasking / threading as you say, but still a handy thing to think about.

I'm still totally ignorant of the new primitives in the original link, so maybe that's why I'm confused, but: are you saying that as of today, wrapping a big parsing job into a promise frees up the event loop? I really don't think that's the case, is it? JSON.parse is gonna be blocking/synchronous whenever it happens.

Can you explain a bit more of the implementation you're describing?

You can use setTimeout to "free up the event loop". Using setTimeout(fun, 0) will run fun after the event loop has been freed up IIRC. NodeJS has a function called setImmediate that does exactly that.

JSON.parse as implemented is going to be blocking. But it's possible to implement an asynchronous, non-blocking JSON parser

See also : http://stackoverflow.com/questions/779379/why-is-settimeoutf...

Edit : requestAnimationFrame is a better alternative to setTimeout(fun, 0), as it allows the browser to update the UI.

Not the parsing part, but the processing part. Assume I've got a big pile of data and am calculating stuff like correlations on it. If I break the process up into chunks, I can go chunk.then(nextChunk).then(afterThat) etc etc. JSON.parse still blocks, but it's the post-processing I'm talking about.
I disagree that parallelism is inherently a low-level specialized thing. There are a lot of operations, like handling any sort of media, that are naturally parallel. If I'm parsing through an image file, I know exactly where it begins and ends, and with very few bits that are dependent on other bits, it just makes sense to be able to spread that operation through the many cores that exist in a modern machine.