So there are two things, there's OS-provided event handling (poll, blocking syscall that schedule another task, OS threads) and there's coroutines (libdill and friends).
OS-level async is what I accuse some devs to underuse, preferring language-level async constructs. I've read a lot of frankly FUD and cargo culting about how inefficient things like pthreads are. Let's not even talk about pre-fork parallelism which is probably the simplest way to use multiple cores when dealing with independent tasks but hardly anybody seems to use these days. I wonder if most devs even realize that it's an option.
In my experience coroutines were never really popular in the C world simply because without GC or at least a borrow checker it's just very hard to write correct code. Avoiding memory violations in C is tricky, avoiding memory violation in async C is asking a lot.
Rust does a lot better here thanks to borrow checking but it still leads to, IMO, very complicated code.
> Let's not even talk about pre-fork parallelism which is probably the simplest way to use multiple cores when dealing with independent tasks but hardly anybody seems to use these days. I wonder if most devs even realize that it's an option.
Speaking from experience: they don't. I recently picked up a Linux kernel development book [1] and after four or five chapters I was able to eliminate several bottlenecks and eliminate latency edge cases in personal projects with a greater understanding of the scheduler algorithm and process priority/affinity/yields.
I think the problem is that the vast majority of developers work on top of cross-platform runtimes that hide any detail that can't be easily implemented for all operating systems. It's been more than a decade since I've used Unix sockets directly in any language and I don't how to set SO_REUSEPORT in Rust. I'd probably have to implement it using `TCPListener::as_raw_fd()` and `unsafe libc::setsockopt`? It's just easier stay sane within the bumpers.
OS-level async is what I accuse some devs to underuse, preferring language-level async constructs. I've read a lot of frankly FUD and cargo culting about how inefficient things like pthreads are. Let's not even talk about pre-fork parallelism which is probably the simplest way to use multiple cores when dealing with independent tasks but hardly anybody seems to use these days. I wonder if most devs even realize that it's an option.
In my experience coroutines were never really popular in the C world simply because without GC or at least a borrow checker it's just very hard to write correct code. Avoiding memory violations in C is tricky, avoiding memory violation in async C is asking a lot.
Rust does a lot better here thanks to borrow checking but it still leads to, IMO, very complicated code.