It is very important in interactive or realtime systems.
It is very important in interactive or realtime systems.
Imagine for the simplest example of a CPU only based game. If I want to render the positions of thousands of soldiers, just do it in a loop. Why would I spawn thousands of coroutines ONLY for the coroutines to do it all in order anyway? Makes no sense.
For some tasks, the static scheduling you described is appropriate (although you could still consider it a form of concurrency), but it needs complete cooperation between tasks and an overall design.
But as soon as you need some sort of fairness, responsiveness, and tasks that are not designed for full cooperation if not outright hostile, you need not only concurrency, but full preemption.
Same thing with the OS. You can build in concurrency without using concurrency primitives because it’s not needed. Right? Let’s say when building an os I had access to spawn go routines in a single threaded context and I used that to build the os. It would be pretty pointless right? You would use a loop here and iterate over the tasks to build the concept of “threading” you wouldn’t need go routines.
It’s strange to talk about it at this level because what’s going on is your implementing “concurrency” from no concurrency. Is having a loop iterate over tasks really concurrency? I would say no, because people think of concurrency like using a threading primitive. If you didn’t fork or activate a call back or await something you didn’t activate “concurrency”.
Concurrency is a higher level concept that only exists where primitives for using concurrency exist.
Thus It makes More sense to frame my argument from the application layer. Without parallelism, concurrency is pointless in the sense that the usage of concurrency primitives given to you by the framework or the OS is pointless.