4 ms·
> We left behind that paradigm in Operating Systems decades ago, and with good reason. I'm curious, what reason? I grew up on Python and C#, and only know asy
by diarrhea 3y ago
> We left behind that paradigm in Operating Systems decades ago, and with good reason.
I'm curious, what reason?
I grew up on Python and C#, and only know async/await, never done real threading (C# async is threading and coroutines under the hood, Python is just coroutines, single-threaded). I find that way of writing code very elegant, as one can encode points of blocking/switching explicitly. A bit like encoding logic into the type system (cliffle has an article on the type state pattern, a good read!): the underlying async implementation can change without code adjustments.
- GolDDranks 3y agoThe reason we left that paradigm in _Operating Systems_ is that OS's are supposed to be resilient. A single buggy app could easily freeze/crash the whole Windows 3.1 system, because the system has the naive assumption that all the apps are benevolent, bug-free, and happily co-operate with time-sharing. Try the same in Windows 2000; you can't, because the system is pre-emptive and forcibly ends the time slots of apps that don't yield. (And possibly kills the app; "MyApp isn't responding" etc.) However, that same reason doesn't apply within a single app, because a single app by a single author _can_ safely co-operate with itself. So co-operative time sharing can work and make sense within single app.
- dale_glass 3y ago> However, that same reason doesn't apply within a single app, because a single app by a single author _can_ safely co-operate with itself. So co-operative time sharing can work and make sense within single app. That's not the case in any non-trivial app. Any real program truly has dozens if not hundreds of authors whose code you're using sight unseen, and which may be difficult to modify. And your program getting stuck can be just as bad as the OS getting stuck. Suddenly your program doesn't reply to API requests, or doesn't relinquish some expensive resource (like an expensive VM), or some such.
- usrbinbash 3y ago> I'm curious, what reason? In days gone by, processes who got to run on the single core that contemporary CPU had available, had to actively relinquish control of the core back to the kernel. If a single process refused to do so, e.g. because the program hang, there was nothing the kernel could do about it, and the entire OS was blocked. The scheduler never ran, no other process would get CPU time, the whole thing was dead in the water, and all you could do was kick the "Reset" button (if present) or pull the power cord and reboot. Obviously, this is a very bad situation for an OS, which runs many processes from many sources. And because of that, we ditched this system, and went on to preemptive multitasking, where control is relinquished back to the scheduler after a time whether the process is okay with that or not. Async basically re-invented that system in userspace. We have an event loop, and we have processes that actively yield control to it. What happens if a subroutine refuses to do so? There is nothing the event loop can do about that. And it's really easy for this to happen. All it needs is a single synchronous call, say, to an external datastore, somewhere deep down in the callstack, and the awesome throughput of async goes bye bye.