>>10793
A year later and I just learned that "modern languages" have what I wanted here and they call it async. Async, among other things, makes it quite easy for the program to go work on a different task when I/O blocks. This is something you can do in C if you implement it yourself, just write a work queue, and every time a job blocks, manually write the code to register with a reactor, save the job's state, and end the job and go do another one. However, this is very laborious and difficult to do yourself. It's also something the language's implementation can do to some extent, some Unix systems got something of the sort for a time with many-to-1 threads implementations which have the effect of task switching in userspace when a syscall blocks, but if the language wasn't designed around it it's inefficient and incomplete.
With async, you only specify the dependencies and parallelism of tasks and the language's runtime handles the rest. However, having a runtime for this reduces performance and modern languages are also inefficient and suck for many, many reasons.
But it turns out Rust is the 1st good modern language and has async, and their async implementation is quite innovative because it's all done at compile time and static unlike other languages. This is one huge performance win for some kinds of multithreaded code, specifically the kind I write. Turns out Rust is so good it has some performance a